Reputation: 124
I'm trying to build this application where the Column 'Package Name' is populated from Core data. The second column has NSButtonCell added in IB and the idea is each time a checkbox is selected I need to get the name of the corresponding zip file in the 'Package Name' column.
I tried something like this
- (void)tableViewSelectionDidChange:(NSNotification *)notification {
NSTableView * tableView = [notification object];
NSInteger rowIndex = [tableView selectedRow];
NSTableColumn *column = [tableView tableColumnWithIdentifier:@"package-name"];
NSCell *cell = [column dataCellForRow:rowIndex];
NSLog(@"Found Value %@",cell.stringValue);
}
But the Value I get each time is different and inconsistent. For example if I select the 6ht checkbox (as shown in the screenshot), I expect to see 4.zip getting printed, but I get something else. How do I fix this ?
Both my Package Name and Installation Status columns are sortable.
Thanks
Upvotes: 0
Views: 1334
Reputation: 90571
Don't consult the cells of the table. Instead, go straight to the data source or, if you're using bindings, the array controller.
First, in NSCell
-based table views, there's typically a single cell object for the whole column. It is reused. It is configured for the first row and asked to draw in the appropriate location for that row. Then, it's configured for the second row and asked to draw in the appropriate location for the second row. Etc. So, retrieving the cell does not give you data for any particular row. The cell will have whatever properties it had the last time it was configured for a row, which may have been a completely different row than you're interested in.
(You could work around this by asking for the prepared cell for a row, using -[NSTableView preparedCellAtColumn:row:]
. But that's really the roundabout way of doing things. The table view will just have to consult the data source in order to prepare the cell.)
If you're using an array controller, then your window/view controller should have an outlet to the array controller. Then, you can get the appropriate model object for a given row by calling:
object = [self.arrayController.arrangedObjects objectAtIndex:row];
If you're interested in the selected objects and your bindings are set up properly, you can just get the selected model object(s) directly from the array controller:
object = self.arrayController.selectedObjects[0];
Or:
for (object in self.arrayController.selectedObjects)
{
// ...
}
Note, though, that checking the checkbox in the second column is a distinct thing from selecting a row. Depending on how the table is configured, the user may be able to do either without the other. For example, they could select a row by clicking in the first column, which would not check the checkbox in the other column. They could also change the selection with the keyboard (e.g. down arrow).
Upvotes: 2