16

I'm using an NSTextView to allow multi-line input. However, due to the nature of my app, users will be more comfortable moving to the next input element when they press TAB.

How can I make TAB exit the NSTextView, while keeping the newline behaviour of the Enter key?

Steve McLeod
  • 51,737
  • 47
  • 128
  • 184

3 Answers3

22

You could implement -textView:doCommandBySelector: in your text view's delegate:

- (BOOL)textView:(NSTextView *)aTextView doCommandBySelector:(SEL)aSelector {
    if (aSelector == @selector(insertTab:)) {
        [[aTextView window] selectNextKeyView:nil];
        return YES;
    }

    return NO;
}

See http://developer.apple.com/documentation/Cocoa/Reference/NSTextViewDelegate_Protocol

Quinn Taylor
  • 44,553
  • 16
  • 113
  • 131
Wevah
  • 28,182
  • 7
  • 83
  • 72
  • 6
    Very nice approach. You could also check for `insertBacktab:` and call `selectPreviousKeyView:` in similar fashion. – Quinn Taylor Sep 23 '11 at 06:49
4

You'll need to implement this in a subclass.

I wrote such a subclass for Translate Text. You're welcome to use it under its BSD license. Here's the header and the implementation file.

… while keeping the newline behaviour of the Enter key?

My main purpose was to send an action to a target when the user presses Enter, and I also have it drop focus from the view. However, both are explicit statements in the code; you can simply comment that code out or delete it.

Peter Hosey
  • 95,783
  • 15
  • 211
  • 370
0

Swift version of the answers of Wevah & Quinn:

func textView(_ textView: NSTextView, doCommandBy commandSelector: Selector) -> Bool {
    switch commandSelector {
    case #selector(NSResponder.insertTab(_:)):
        textView.window?.selectNextKeyView(nil)
        return true
    case #selector(NSResponder.insertBacktab(_:)):
        textView.window?.selectPreviousKeyView(nil)
        return true
    default:
        return false
    }
}
Manabu Nakazawa
  • 1,983
  • 22
  • 23