NSResponder 定义了许多与键盘操作相关的操作,例如 moveUp:
、 moveUpAndModifySelection:
和 moveToBeginningOfLine:
。除了不是通过按修饰键触发的操作(例如 moveUp:
只是 Up
箭头键),我无法在我的自定义 NSView
上调用任何操作。
这是设置:
Custom View
。 NSView
STView
STView
只是覆盖 acceptsFirstResponder
以返回 YES
在这个设置中,我的
STView
实例将正确接收所有键盘事件(包括那些在 Ctl-A
和 performKeyEquivalent:
中都带有像 keyDown:
这样的修饰符的事件,正如预期的那样。(这两种方法都被注释掉以供下文讨论。)如果我提供
moveUp:
的实现,如 NSResponder
中所定义,那么当用户按下 moveUp:
箭头键时, Up
会被正确调用。令人困惑的是,每当使用修饰键按下
moveUp:
箭头键时,也会调用 Up
。当按住修饰键(例如: Ctl-Up
)时,我希望调用适当的键盘操作方法。前任:
Ctl-Up
-> moveUp:
(预期:scrollPageUp:
)Alt-Up
-> moveUp:
(预期:moveToBeginningOfParagraph:
)Shift-Up
-> moveUp:
(预期:moveUpAndModifySelection:
)Command-Up
-> moveUp:
(预期:moveToBeginningOfDocument:
)对于所有键/修饰符组合,此模式都会重复。
Apple 文档中的两个方面似乎相关:
通读该文档,系统似乎负责将关键事件映射到相应的关键操作。事实上,当没有按下修饰键时,这对我有用。但是当按下修饰键时,事件就像任何其他事件一样被处理并通过正常的响应者链传递。
(我可以看到通过
NSApplication sendEvent
传入的修饰键事件,尽管 NSApplication sendAction:to:from:
从未被调用,并继续向下查看 View 层次结构,鉴于我阅读了上述文档,我期望这样做。文档提示文本编辑 View 可能会有不同的处理方式。这些键盘操作是否仅发送到编辑文本的 View ?如果没有,那么当用户按下
moveUpAndModifySelection:
时,如何在他们的自定义 NSView
类上获得类似 Shift-Up
的消息?作为引用,我正在使用此图表进行键盘绑定(bind),但坦率地说,我已经尝试了几乎所有组合,无论是否列出:
归根结底,我可能只是覆盖
keyDown:
并手动处理我感兴趣的所有组合,但我希望至少了解为什么这对我来说不起作用。(请注意,此处的预期应用程序是允许用户导航类似网格的项目 View ,很像集合 View 。)
任何提示、建议或意见将不胜感激。
更新:
如果您在
keyDown
中执行以下操作- (void)keyDown:(NSEvent *)theEvent {
...
[self interpretKeyEvents:[NSArray arrayWithObject:theEvent]];
}
然后将在您的自定义 View 上调用“正确”操作。我认为这是因为我感兴趣的 Action 是类似文本的 Action ,它需要输入管理器来解释并转换为适当的 Action 。
我仍然不完全清楚为什么
moveUp:
被正确调用。响应者链中的谁识别出 Up
箭头键被按下,然后发出 moveUp:
消息? 最佳答案
这是对您的自我回答的一种回复,这更像是问题的延伸。
是的,在大多数情况下,需要调用 -[NSResponder interpretKeyEvents:]
或 -[NSTextInputContext handleEvent:]
来让键绑定(bind)系统向您发送绑定(bind)的操作方法。
至于为什么你得到 -moveUp:
,我在一个简单的自定义 View 类中实现了以下内容:
- (BOOL) acceptsFirstResponder
{
return YES;
}
- (void) moveUp:(id)sender
{
NSLog(@"%@", [NSThread callStackSymbols]);
}
记录了以下调用堆栈:
0 TestKeyUp 0x000000010000182d -[KeyView moveUp:] + 48
1 AppKit 0x00007fff85e44012 -[NSWindow _processKeyboardUIKey:] + 325
2 AppKit 0x00007fff85ab1075 -[NSWindow keyDown:] + 94
3 AppKit 0x00007fff8589e206 forwardMethod + 104
4 AppKit 0x00007fff8589e206 forwardMethod + 104
5 AppKit 0x00007fff8596c0c7 -[NSWindow sendEvent:] + 8769
6 AppKit 0x00007fff858a0afa -[NSApplication sendEvent:] + 4719
7 AppKit 0x00007fff858376de -[NSApplication run] + 474
8 AppKit 0x00007fff858303b0 NSApplicationMain + 364
9 TestKeyUp 0x000000010000176d main + 33
10 TestKeyUp 0x0000000100001744 start + 52
11 ??? 0x0000000000000001 0x0 + 1
NSWindow
处理向上箭头键作为“键盘界面控制”的一部分。这是 partially documented ,但并没有明确表示它会调用诸如 -moveUp:
之类的方法。显然,这就是它的实现方式。关于objective-c - 为什么没有调用 NSResponder 的键盘操作?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/22725329/