开发者

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开发者_如何学Go 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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜