I’ve seen many ways to implement delete in an NSTableView. Many are good. Many hardcode references to something they shouldn’t, and those are bad.
Here’s an easy way:
Subclass NSTableView and override keyDown:
- (void)keyDown:(NSEvent *)theEvent { // handle delete unichar key = [[theEvent charactersIgnoringModifiers] characterAtIndex:0]; if (key == NSDeleteCharacter && self.selectedRow != -1) { [NSApp sendAction:@selector(delete:) to:nil from:self]; } else { [super keyDown:theEvent]; } }
This just lets the responder chain take care of it. Your window controller can easily handle it by just implementing delete:
- (IBAction)delete:(id)sender { if (self.tableView.selectedRowIndexes.count > 0) { [_tableView beginUpdates]; [[self _patternSequence] removeChildrenAtIndexes:self.tableView.selectedRowIndexes]; [_tableView endUpdates]; } }
EDIT: I probably should only call super keyDown if it wasn’t the delete key…otherwise we beep.
I might be missing something obvious, but the line
[[self _patternSequence] removeChildrenAtIndexes:self.tableView.selectedRowIndexes];
could do with a bit more explanations. Is _patternSequence the datasource of the NSTableView ?
Hi Guillaume —- that’s my model; it is backed by a core data obect. Maybe I’ll do a post on how to update your model and have a view based tableview animate along with it.
corbin
Hi Corbin,
Yes please, that would be a nice follow-up to this one :)
Yeah we need a little more detail. In particular, I’m surprised I don’t see any “reloadData”. Maybe it’s because you’re using Cocoa Bindings ? or are the beginUpdates/endUpdates enough in all scenarios (with or without bindings ?)
I’m glad you’re writing new Cocoa post. Those were missing (a lot). Thanks
Yeah, I am using CoreData…but I have it semi-using bindings.
Delete is easy, but what about copy? Can’t send the copy: action to nil because it’ll just get sent back to itself since the tableview is first responder.