4

I've got an NSTableView. While editing, if I hit tab it automatically jumps me to the next column. This is fantastic, but when I'm editing the field in the last column and I hit tab, I'd like focus to jump to the first column of the NEXT row.

Any suggestions?

Thanks to Michael for the starting code, it was very close to what ended up working! Here is the final code that I used, hope it will be helpful to someone else:

- (void) textDidEndEditing: (NSNotification *) notification {
    NSInteger editedColumn = [self editedColumn];
    NSInteger editedRow = [self editedRow];
    NSInteger lastColumn = [[self tableColumns] count] - 1;

    NSDictionary *userInfo = [notification userInfo];

    int textMovement = [[userInfo valueForKey:@"NSTextMovement"] intValue];

    [super textDidEndEditing: notification];

    if ( (editedColumn == lastColumn)
        && (textMovement == NSTabTextMovement)
        && editedRow < ([self numberOfRows] - 1)
        )
    {
        // the tab key was hit while in the last column, 
        // so go to the left most cell in the next row
        [self selectRowIndexes:[NSIndexSet indexSetWithIndex:(editedRow+1)] byExtendingSelection:NO];
        [self editColumn: 0 row: (editedRow + 1)  withEvent: nil select: YES];
    }

}
Kenny Wyland
  • 20,844
  • 26
  • 117
  • 229
  • I didn't see that you'd posted the modified code here. Nice! As I asked below, any idea how to adapt this to a table with a button cell in the rightmost column? – paulmelnikow Oct 18 '11 at 17:35
  • If you want the tabbing to skip over that column, just change lastColumn to be count - 2. If you want the tab to jump to that button... I'm not sure. I've never dealt with that before. – Kenny Wyland Oct 19 '11 at 15:44
  • Tab already stops there (this is set in System Preferences). When I tab *out* of it, I want to go to the next row. – paulmelnikow Oct 19 '11 at 17:13
  • Thanks. If I post another question I'll link to it here. – paulmelnikow Oct 19 '11 at 22:37

2 Answers2

3

You can do this without subclassing by implementing control:textView:doCommandBySelector:

-(BOOL)control:(NSControl *)control textView:(NSTextView *)textView doCommandBySelector:(SEL)commandSelector {

    if(commandSelector == @selector(insertTab:) ) {
        // Do your thing
        return YES;
    } else {
        return NO;
    }   
}

(The NSTableViewDelegate implements the NSControlTextEditingDelegate protocol, which is where this method is defined)

This method responds to the actual keypress, so you're not constrained to the textDidEndEditing method, which only works for text cells.

Bob Vork
  • 2,927
  • 28
  • 32
1

Subclass UITableView and add code to catch the textDidEndEditing call.

You can then decide what to do based on something like this:

- (void) textDidEndEditing: (NSNotification *) notification
{
    NSDictionary *userInfo = [notification userInfo];

    int textMovement = [[userInfo valueForKey:@"NSTextMovement"] intValue];

    if ([self selectedColumn] == ([[self tableColumns] count] - 1))
        (textMovement == NSTabTextMovement)
    {
        // the tab key was hit while in the last column, 
        // so go to the left most cell in the next row
        [yourTableView editColumn: 0 row: ([self selectedRow] + 1)  withEvent: nil select: YES];
    }

    [super textDidEndEditing: notification];
    [[self window] makeFirstResponder:self];

} // textDidEndEditing

This code isn't tested... no warranties... etc. And you might need to move that [super textDidEndEditing:] call for the tab-in-the-right-most-cell case. But hopefully this will help you to the finish line. Let me know!

Michael Dautermann
  • 88,797
  • 17
  • 166
  • 215
  • Any idea how to adapt this to a table view with a button cell in the rightmost column? There's no call to textDidEndEditing when it loses focus. – paulmelnikow Oct 18 '11 at 17:02