views:

239

answers:

2

I have a small NSTableView with a checkbox. Whenever the checkbox is not checked, I want one of the adjacent NSCells to be grayed out and inaccessible.

However, I can't figure out how to address only one specific cell. -dataCellForRow of NSTableColumn always changes the template cell for the whole table column.

How can I access one single cell?

Edit: I fill the table view using the NSTableViewDataSource protocol.

+1  A: 

Could you bind the editability of that column to the value that is being displayed in the checkbox? i.e. if it is checked, it is editable, otherwise it isn't?

I am trying to remember the exact editor interface, and I am not next to my Mac at home, so I am not able to do a total walk through on it - hope this can point you in the right direction.

aperkins
I thought about that, but I think I would need an array controller to have actual access to the individual data entries?
BastiBechtold
@Paperflyer I am not positive - it has been a while since I attempted to do something like that in a table. I would need to look it up. How are you getting the information for each of the cells otherwise? How is it getting propagated?
aperkins
+5  A: 

You don't "access a cell". NSTableView asks for data only when necessary, you don't populate it or control it directly.

Instead, you create a controller object which implements the NSTableViewDatasource and optionally NSTableViewDelegate protocols. The table view then sends the datasource messages to your controller and your controller supplies the appropriate data.

You can allow editing for an object displayed in the table view by implementing the ‑tableView:setObjectValue:forTableColumn:row: datasource method. This method will be called on your controller object when the user clicks the checkbox. It is your controller's responsibility to update the model appropriately.

When the model is updated, your controller should tell the table view to reload. The table view will then ask your controller for the value of any cell that requires display using the ‑tableView:objectValueForTableColumn:row: datasource method. This will include the cell that you need to disable. Your controller needs to supply the appropriate value for the cell.

If you need more control of the cell, you can implement the ‑tableView:willDisplayCell:forTableColumn:row: delegate method. This is called just before a cell is displayed, and you can modify the cell appropriately.

More info about using data sources is in the docs.

The other option (instead of using a datasource) is to use Cocoa Bindings and an NSArrayController that you bind to your collection of model objects. In that case, you can bind the Enabled binding of the table column to some property of your model object that controls the cell's enabled state. It is your responsibility to ensure that the state of that property is correct.

If you need to make the property dependent on the value of another property, you can use the dependent key mechanism outlined in the Key-Value Observing documentation.

Rob Keniger
+1 - thanks for so eloquently explaining what I was struggling to remember :D
aperkins