I’ve previously shown you how to populate an NSTableView using Bindings and an array controller. Today I’ll show you how to do it in code.
It’s relatively simple and very similar to powering a UITableView. The main difference is that in Cocoa we don’t have a controller object that comes bundled with our view, so we’ll have to create one manually (or use an existing class). Here are the steps:
* add an NSTableView to your XIB file
* create a controller class based on NSObject (I’ll call mine TableController)
* drag an NSObject object into the XIB (that blue box)
* associate it with your custom controller object (i.e. TableController)
* set the data source and implement its methods
In this example I’m using the numbers 1-10 in two arrays: as numbers, and as written out values – so that two columns of the table view can be populated with different items.#pragma mark - Custom Initialisers
- (NSArray *)numbers {
if (!_numbers) {
_numbers = @[@"1", @"2", @"3", @"4", @"5", @"6", @"7", @"8", @"9", @"10"];
}
return _numbers;
}
- (NSArray *)numberCodes {
if (!_numberCodes) {
_numberCodes = @[@"One", @"Two", @"Three", @"Four", @"Five", @"Six", @"Seven", @"Eight", @"Nine", @"Ten"];
}
return _numberCodes;
}Next we’ll implement the following two methods: the first for returning the number of rows, and the second for returning the relevant data in each row:#pragma mark - Table View Data Source
- (NSInteger)numberOfRowsInTableView:(NSTableView *)tableView {
// how many rows do we have here?
return self.numbers.count;
}
- (id)tableView:(NSTableView *)tableView objectValueForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row {
// populate each row of our table view with data
// display a different value depending on each column (as identified in XIB)
if ([tableColumn.identifier isEqualToString:@"numbers"]) {
// first colum (numbers)
return [self.numbers objectAtIndex:row];
} else {
// second column (numberCodes)
return [self.numberCodes objectAtIndex:row];
}
}Notice that in the second method we’re not referencing the columns with a number (like we do with rows). That’s because the user could reorder or remove columns. Instead we’re using the column identifier which you can set in IB.
Reacting to selections
If you want to react to user selections in your code you need to implement the NSTableViewDelegate Protocol and also connect your table view’s delegate to the above class. Then simply implement this method and you’re notified when a user clicks a row:#pragma mark - Table View Delegate
- (void)tableViewSelectionDidChange:(NSNotification *)notification {
NSTableView *tableView = notification.object;
NSLog(@"User has selected row %ld", (long)tableView.selectedRow);
}Unlike in iOS, we’re not directly passed the table view object – but we can grab it from the notification. Note that the log message will be off by one because the rows start at 0 rather than 1.
Demo Project
Here’s a demo project with the above steps implemented:
* https://github.