keyDown:(NSEvent *)event is not invoked when the focus is on a text field

cocoa, objective-c

Solution

Are you sure that you need to catch the key down event for that?

Apple state in the docs that fiddling with `keyDown:` for controls is kind of a last resort, to be used only if the normal Cocoa architecture around delegates does not do what you want.

If the purpose is to catch the enter button pressed, notice that this event in a text field triggers the `textDidEndEditing` delegate method (or notification, if you prefer that).

So if you implement `controlTextDidEndEditing:` in a delegate for your `NSTextField` you should be able to react to the event. This notification (and the relative delegate method) is sent when the field editor ends editing.

If you prefer to catch the event one step earlier (before the field editor ends editing), you can implement the delegate method `control:textView:doCommandBySelector:` which lets you intercept specific key events (such as the return key) and modify the behaviour of the editor.

An example could be the following:

- (BOOL)control:(NSControl *)control textView:(NSTextView *)fieldEditor doCommandBySelector:(SEL)commandSelector
{
    BOOL retval = NO;
    if (commandSelector == @selector(insertNewline:)) {
        retval = YES; // Handled

        // Do stuff that needs to be done when newLine is pressed
    }
    return retval;
}

There is a lot of documentation on Apple's site about it, for instance an introduction here.

Problem

I've overridden `- (void)keyDown:(NSEvent *)event` in my `NSPanel` subclass. However it is invoked only if the focus is not on a `NSTextField` inside my panel. However I need to catch the event "Enter button pressed" regardless of if the focus is on the text field or the panel. How to make sure it is always invoked?

Original source