简体   繁体   中英

How to auto resize table column when double clicking on Cocoa?

I want to auto resize table column to its content width when double clicking its header (resize cursor is showing), like on iTunes.

Anyone know how to do it ?

Thanks in advance

Look at the NSTableView method setDoubleAction: . You can probably set it up from Interface Builder, too - I didn't check. From the documentation :

setDoubleAction:

Sets the message sent to the target when the user double-clicks an uneditable cell or a column header to a given selector.

 - (void)setDoubleAction:(SEL)aSelector

Parameters
aSelector
The message the receiver sends to its target when the user double-clicks an uneditable cell or a column header.

Discussion
If the double-clicked cell is editable, this message isn't sent and the cell is edited instead. You can use this method to implement features such as sorting records according to the column that was double-clicked. See also clickedRow which you can use to determine if a row was clicked rather than the column heading.

For the method to have any effect, the receiver's action and target must be set to the class in which the selector is declared. See Action Messages for additional information on action messages.

If you're using a view-based table view and targeting macOS 10.6 or above, you can implement the NSTableViewDelegate method tableView(_:sizeToFitWidthOfColumn:) .

Here is a simple Swift implementation I did which proved to be fast enough for a table with 10 columns and a few hundred rows:

func tableView(_ tableView: NSTableView, sizeToFitWidthOfColumn column: Int) -> CGFloat {
    var longestWidth = 0.0
    var text: String

    for row in 0..<tableView.numberOfRows {
        let item = myDataSource[row]

        switch column {
            case 0: text = item.firstName
            case 1: text = item.middleName
            case 2: text = item.lastName
            case 3: text = item.streetNumber
            case 4: text = item.city
            case 5: text = item.region
            case 6: text = item.country
            case 7: text = item.bloodType
            case 8: text = item.gender
            case 9: text = item.nationality
            default: text = ""
        }

        let textSize = text.size(withAttributes: [
            // .regular requires macOS 10.12+
            .font: NSFont.systemFont(ofSize: NSFont.systemFontSize(for: .regular))
        ])

        if textSize.width > longestWidth {
            longestWidth = textSize.width
        }
    }

    return longestWidth + 8 // some padding
}

If it becomes slow, you probably should calculate the size of the visible rows and a dozen more above and bellow or find a better implementation.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM