NSResponder defines numerous actions that are related to keyboard actions like moveUp:
, moveUpAndModifySelection:
and moveToBeginningOfLine:
. With the exception of the actions that aren't triggered by pressing a modifier key (e.x. moveUp:
is simply the Up
arrow key) I can't get any of the actions to be called on my custom NSView
.
Here's the setup:
- Xcode 5.1 / 10.9
- Basic Cocoa app with nothing more then a
Custom View
added to the main window. - This custom view is just an
NSView
of classSTView
STView
does nothing more than overrideacceptsFirstResponder
to returnYES
In this setup, my STView
instance will correctly receive all keyboard events (including those with a modifier like Ctl-A
in both performKeyEquivalent:
and keyDown:
, as expected. (Both methods are commented out for the discussion below.)
If I provide an implementation for moveUp:
, as defined in NSResponder
then moveUp:
is correctly called when the user presses the Up
arrow key.
Confusingly, moveUp:
is also called whenever the Up
arrow key is pressed with a modifier key. When a modifier key is being held (e.x.: Ctl-Up
) I would expect the appropriate keyboard action method to be called.
Ex:
Ctl-Up
->moveUp:
(expected:scrollPageUp:
)Alt-Up
->moveUp:
(expected:moveToBeginningOfParagraph:
)Shift-Up
->moveUp:
(expected:moveUpAndModifySelection:
)Command-Up
->moveUp:
(expected:moveToBeginningOfDocument:
)
This pattern repeats itself for all key/modifier combinations.
Two areas in Apple's documentation seem relevant:
Reading through that documentation, it looks like the system is responsible for mapping key events to their appropriate key action. And indeed, this works for me when a modifier key is not pressed. But when a modifier key is pressed, then the event is just being handled like any other event and passed through the normal responder chain.
(I can see the modifier key event coming in through NSApplication sendEvent
, though NSApplication sendAction:to:from:
is never called, and continuing down the view hierarchy, which I would expect given my reading of the documentation above.
The documentation hints that text editing views might be treated differently. Are these keyboard actions only sent to views that edit text? If not, then how does one get a message like moveUpAndModifySelection:
to be called on their custom NSView
class when the user presses Shift-Up
?
For reference, I'm using this chart for keyboard bindings, though to be frank I've tried just about every combination, listed or not:
At the end of the day, I could likely just override keyDown:
and manually handle all the combinations I'm interested in, but I was hoping to at least understand why this isn't working as intended for me.
(Note that the intended application here is to allow the user to navigate a grid-like view of items, much like a collection view.)
Any tips, advice or comments would be much appreciated.
Update:
If you do the following in your keyDown
- (void)keyDown:(NSEvent *)theEvent {
...
[self interpretKeyEvents:[NSArray arrayWithObject:theEvent]];
}
Then the "correct" actions will be called on your custom view. I assume this is because the actions I'm interested in are text-like actions, which require the input manager to interpret and convert to their appropriate actions.
It's still not entirely clear to me why moveUp:
is properly getting called. Who in the responder chain is recognizing the Up
arrow key being pressed and then sending out a moveUp:
message?