Search code examples
cocoatextfieldnstablecellview

Updated NSTableCellView.textField NOT updated in table display.


I have a feeling this table cell display problem has a simple answer but, I clearly need greater wisdom than mine to find it.

Here's my textbook controller, delegate and datasource class for the table and the enclosing view ...

import Cocoa

class Table8020ViewController: NSViewController, NSTableViewDelegate, NSTableViewDataSource {

    var tokenText: [String] = ["alpha", "beta", "gamma", "delta", "epsilon", "zeta"]

    override func viewDidLoad() {
        super.viewDidLoad()
    }

    func numberOfRowsInTableView(aTableView: NSTableView) -> Int {
        println("numberOfRowsInTableView = \(tokenText.count)")
        return tokenText.count
    }

    func tableView(aTableView: NSTableView, objectValueForTableColumn aTableColumn: NSTableColumn?, row rowIndex: Int) -> AnyObject? {

        var result = aTableView.makeViewWithIdentifier(aTableColumn!.identifier, owner: self) as! NSTableCellView
            println("textField in  = \(result.textField!.stringValue)")

            result.textField!.stringValue = tokenText[rowIndex]

            println("textField out = \(result.textField!.stringValue)")
            return result
    }
}

I log the updates to the .textField which seems to work ok.

numberOfRowsInTableView = 6
textField in  = Table View Cell
textField out = alpha
textField in  = Table View Cell
textField out = beta
textField in  = Table View Cell
textField out = gamma
textField in  = Table View Cell
textField out = delta
textField in  = Table View Cell
textField out = epsilon
textField in  = Table View Cell
textField out = zeta

But the actual table display retains the original interface builder values! 'Table View Cell' Something mysterious appears to be happening after after the 'return result'.

I'm using the latest Xcode Version 6.3 (6D570) with Swift V1.2


Solution

  • You're making a couple of mistakes.

    Firstly you're returning the wrong kind of value from tableView:objectValueForTableColumn:row. This method isn't requesting a view instance, it's requesting the object that your view instance will be representing. In other words it wants to know what model object the view will be displaying. In each case your model object is very simple - it's one of the strings in the tokenText array.

    func tableView(tableView: NSTableView,
        objectValueForTableColumn tableColumn: NSTableColumn?,
        row: Int) -> AnyObject? {
            return tokenText[row]
    }
    

    Secondly you've failed to implement tableView:viewForTableColumn:row:. This is where you create a view for each cell in your table and tell that view which bits of the model object you want to display. In each case your model object is just a string, so you essentially tell the view to display the entire model object in its textField:

    func tableView(tableView: NSTableView,
        viewForTableColumn tableColumn: NSTableColumn?,
        row: Int) -> NSView? {
    
            var view = tableView.makeViewWithIdentifier(tableColumn!.identifier,
                owner: self) as! NSTableCellView
            view.textField!.stringValue = tokenText[row]
    
        return view
    }