Migrating from a cell-based to a view-based NSTableView
By: Brian Webster |
As I mentioned in my last post, I’m currently learning about how a view based NSTableView differs from an old style NSCell based table view (or technically in my case, an NSOutlineView). I’m taking notes on what all is different, and figured I’d post it here too, in case it helps anyone else
Like before, you can use either bindings or a data source to provide data to your table view.
However, with cell based views, you would bind each individual column, or provide different object values for each row+column in -tableView:objectValueForTableColumn:row: With view-based tables, it’s just a single ‘content’ binding that binds each row to an object value, and that same object value is set as the objectValue for each of your cell views. Each view can show different data by binding to different properties of the objectValue, e.g. the name column would bind to “objectValue.name”, etc.
With a data source, you don’t actually need to implement -tableView:objectValueForTableColumn:row:, as you can just configure your view yourself before returning it from -tableView:viewForTableColumn:row:. However, you can implement the object value data source method if you want, and NSTableView will do just like bindings, and use that as the objectValue for the cell view.
Editing cells is no longer handled by the table view itself, and doesn’t call a setObject data source method to pass on the value. Instead, you’re supposed to use bindings or hook up target/action from the subviews in your cell’s view to modify the model object as needed. NSTableCellView handles this mostly automatically for you though. This does make it much easier to have a single cell handle editing multiple bits of data though, if needed, since you no longer have to work under the assumption that one cell displays just one value.
This also means that starting an edit programatically works a bit differently too, since NSTableView is no longer doing the work of setting up the field editor for your NSTextFieldCell like it did before. According to the docs, it tries to make the view in that row/column the first responder, and then it’s up to the view to start editing? Or something? I need to play with this one to figure out how it really works.
With cell-based tables, each table column just had a single NSCell instances, stored in its dataCell property. You could give it custom cells using the -tableView:dataCellForTableColumn:row: method, to have different types of cells in different rows. For view-based tables, you can just drag multiple views into a single table column, and give each one a unique identifier string. Then you can just call -makeViewWithIdentifier:owner: to have it make a new instance of that view each time you need it. This makes it really easy to have heterogenous cells in your table.
That’s all I’ve got for now, I’ll post more if I discover anything else as I go along.