NSTableView + Delete Key

What I usually do is create a new menu item in your application's menu bar. Something like:

File -> Delete ${Name of Item}

Then you can link that NSMenuItem in Interface Builder to point to an IBAction method defined somewhere on either your app delegate or some other controller. The implementation for this method should delete the item from your model, and refresh the NSTableView.

The advantage to making an NSMenuItem out of the action is that:

  1. You can give the item a keyboard shortcut in Interface Builder. (Like the delete key.)
  2. Users who are not familiar with your application, afraid to press the delete key, or do not have access to a keyboard for whatever reason, can still make use of this functionality.

After 10.10, NSViewController is part of the responder chain. So the easiest way is to implement keyDown in your subclassed NSViewController


There is no need to subclass and catch keyDown in NSViewController.

The Delete menu item in the menu Edit is connected to the selector delete: of First Responder. If there is no Delete menu item, create one and connect it to delete: of First Responder (red cube).

  • Assign a key equivalent to the Delete menu item ( or ⌘⌫)
  • In the view controller implement the IBAction method

    Swift: @IBAction func delete(_ sender: AnyObject)

    Objective-C: -(IBAction)delete:(id)sender

    and put in the logic to delete the table view row(s).


I've implemented something similar to LTKeyPressTableView. However, I use array controllers, so in my subclass I added IBOutlet NSArrayController * relatedArrayController. Instead of handling delete request in a delegate, I handle it directly in the subclass since my subclass specifically deals with adding handling of Delete key. When I detect keypress for delete key, I'm just calling [relatedArrayController delete:nil];.

IRTableView.h:

#import <Cocoa/Cocoa.h>

@interface IRTableView : NSTableView {
    IBOutlet NSArrayController * relatedArrayController;
}

@end

and IRTableView.m:

#import "IRTableView.h"


@implementation IRTableView


- (void)keyDown:(NSEvent *)event
{
    // Based on LTKeyPressTableView.
    //https://github.com/jacobx/thoughtkit/blob/master/LTKeyPressTableView

    id delegate = [self delegate];

    // (removed unused LTKeyPressTableView code)

    unichar key = [[event charactersIgnoringModifiers] characterAtIndex:0];
    if(key == NSDeleteCharacter)
    {
        if([self selectedRow] == -1)
        {
            NSBeep();
        }

        BOOL isEditing = ([[self.window firstResponder] isKindOfClass:[NSText class]] && 
                          [[[self.window firstResponder] delegate] isKindOfClass:[IRTableView class]]);
        if (!isEditing) 
        {
            [relatedArrayController remove:nil];
            return;
        }

    }

    // still here?
    [super keyDown:event];
}

@end

End result is quite IB-friendly for me, and a quite simple solution for use in a Cocoa Bindings+Core Data application.