Search code examples
notificationsnstableviewcolumn-width

Where to Set Column Width in NSTableView After Updates


I managed to write a function to set the column width by max string length. I need this to prevent long strings from clipping, wrapping etc. My problem is now, where do I put the function. In other words when do I know when the tableview finished loading or updating? I cant find any available notifications for NSTableView.

here is my func:

func columnWidthByMaxStringLength(forColumn: Int) -> CGFloat {

    let table = equationTableView!
    var width = 0
    for i in 0...table.numberOfRows-1 {
        let view = table.view(atColumn: forColumn, row: i, makeIfNecessary: true)
        let size = view?.fittingSize
        width = max(width, Int((size?.width)!))
    }

    return CGFloat(width)
}

I tried to call this function within the NSTableView delegate func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? but it is not the right place. It throws an error.


Solution

  • The width of the column can be calculated when the table view and the data are loaded, before updating the table view. You can reuse the cell view.

    For example:

    override func viewDidLoad() {
        super.viewDidLoad()
        self.data = …
        self.sizeToFit(column: tableView.column(withIdentifier: NSUserInterfaceItemIdentifier("name")))
        self.tableView.reloadData()
    }
    
    func sizeToFit(column: Int) {
        if let view = self.tableView.view(atColumn: column, row: 0, makeIfNecessary: true) as? NSTableCellView {
            let key = self.tableView.tableColumns[column].identifier.rawValue
            var width = self.tableView.tableColumns[column].minWidth
            for object in self.data {
                view.textField?.objectValue = object[key]
                let size = view.fittingSize
                width = max(width, size.width)
            }
            self.tableView.tableColumns[column].width = width
        }
    }