NSTableView and backspace event (delete row) - fieldeditor/firstresponder?
Asked Answered
B

4

10

Is it possible to make my NSTableView accept a deleteevnt (backspace og even cmd+backspace) ? I have an NSMenu where i have my delete-menu-item connected to my first responder object in the nib.

Any pointers?

Biome answered 9/2, 2011 at 14:35 Comment(0)
M
2

You could create a subclass of NSTableView, overriding keyDown like so:

- (void)keyDown:(NSEvent *)theEvent
{

    unichar key = [[theEvent charactersIgnoringModifiers] characterAtIndex:0];
    if(key == NSDeleteCharacter) 
    {

        [self deleteItem];
        return;
    }

    [super keyDown:theEvent];

}

Then make sure that any NSTableView that you want to have the delete functionality uses your subclass in Interface Builder instead of the regular NSTableView.

You can implement the - (void)deleteItem method for example like this:

- (void)deleteItem
{
    if ([self numberOfSelectedRows] == 0) return;

    NSUInteger index = [self selectedRow];

    [documentController deleteItemWithIndex:index];

}
Majordomo answered 29/2, 2012 at 18:5 Comment(2)
If you have several views that you need to track separately from the same documentController, you can identify them using tags, i.e enter a tag for the view in Interface Builder, and then check the value of the self.tag value in the keyDown: method.Majordomo
Sorry but this answer should not be marked correct. This solution is absolutely not the best practice.Perdue
B
11

This is a modern solution using NSViewController and First Responder.

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).

No subclass needed.

Balf answered 29/6, 2017 at 18:22 Comment(3)
From where does the delete action comes? I can see a lot of actions like this in IB, but NSResponder does not define all of them.Haemolysin
@ IBAction or @ objc give the same result. Missing this makes Delete menu item to be greye outBianchi
@Haemolysin Good question. For iOS, they are defined in a UIResponderStandardEditActions protocol; the Cocoa Event Handling Guide calls them Standard Action Methods for Selecting and Editing and points to NSResponder where they are not documented. Curious.Fischer
T
9

One approach which is easy to implement:

  1. add +/- buttons to your interface in IB and connect them to a deleteRecord IBAction
  2. with the delete (-) button selected in IB, navigate to Attributes Inspector > Button > Key Equivalent
  3. click in the box to start recording your keypress, then hit the Delete/Backspace key

When you build your project, given that you implement the deleteRecord method, a Backspace keypress will delete records from your tableview

Torto answered 13/2, 2011 at 17:28 Comment(1)
Yeah i have figured this out, but it gives me trouble when i more than 1 table view at a time :)Biome
P
6

The correct way of implementing this functionality is by using key-bindings:

  1. Select the delete menu item in IB and set it's key equivalent to the backspace key for example.
  2. Connect the menu items action to a method you wrote for handling the task. This method will be found for you automatically up the responder chain, when you connect it through the first responder.
  3. Implement your delete functionality.

Depending upon which kind of application you write, there are validation delegate methods. By which means you can set the menu items enabled state. For a document based application this validation happens through - (BOOL)validateUserInterfaceItem:(id)anItem.

Perdue answered 28/2, 2013 at 16:43 Comment(0)
M
2

You could create a subclass of NSTableView, overriding keyDown like so:

- (void)keyDown:(NSEvent *)theEvent
{

    unichar key = [[theEvent charactersIgnoringModifiers] characterAtIndex:0];
    if(key == NSDeleteCharacter) 
    {

        [self deleteItem];
        return;
    }

    [super keyDown:theEvent];

}

Then make sure that any NSTableView that you want to have the delete functionality uses your subclass in Interface Builder instead of the regular NSTableView.

You can implement the - (void)deleteItem method for example like this:

- (void)deleteItem
{
    if ([self numberOfSelectedRows] == 0) return;

    NSUInteger index = [self selectedRow];

    [documentController deleteItemWithIndex:index];

}
Majordomo answered 29/2, 2012 at 18:5 Comment(2)
If you have several views that you need to track separately from the same documentController, you can identify them using tags, i.e enter a tag for the view in Interface Builder, and then check the value of the self.tag value in the keyDown: method.Majordomo
Sorry but this answer should not be marked correct. This solution is absolutely not the best practice.Perdue

© 2022 - 2024 — McMap. All rights reserved.