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

2

1

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

Wurtz answered 3/3, 2010 at 4:45 Comment(2)
did you find a solution to this?Conjunctive
@Conjunctive You can check my answer.Skate
O
1

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.

Outline answered 3/3, 2010 at 4:54 Comment(1)
It's executed when double clicking header but not when resize cursor is showing.Wurtz
S
0

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.

Skate answered 21/5, 2022 at 19:15 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.