缺少有意义的键组合上的keyUp事件(例如“选择直到行首”)

我有一个NSTextField,它用作扩展的NSTextFieldCell,它创建一个自定义字段编辑器,拦截并记录关键事件 . (了解关键事件对于应用程序很重要,但是文本字段仍然应该照常工作,通过调用 [super ...] 方法) . 这是官方文档对此问题的建议 .

键入时我确实收到了大多数 keyUp 事件,但在某些情况下我没有收到 . 当按下一个附有动作的组合键时,似乎会发生这种情况 . 例如 . Cmd-Shift-Left 未发出keyUp事件 . 该输入使得从点到开头的整行显示为选中,但是当收到 keyDown 时 .

在缺少它的情况下,当通过覆盖它来查看 -performKeyEquivalent: 时,我看到它被调用 . 为什么keyUp没有交付?

回答(3)

2 years ago

这就是事件架构的设置方式 . 发送密钥等效消息比发送作为其中一部分的各种密钥的消息更受欢迎 . 特别是"Handling Key Events,","Handling Key Equivalents."看起来你可以继承 NSApplication 并覆盖 -sendEvent: 来调度这些事件,但是你可能会破坏比你添加的功能更多的功能 .

2 years ago

对于其他人来说,这是“修复”它的代码:

- (void)sendEvent:(NSEvent *)event {
    if ([event type] == NSKeyUp && ([event modifierFlags] & NSCommandKeyMask))
        [[self keyWindow] sendEvent:event];
    else
        [super sendEvent:event];
}

2 years ago

为了保持正常的应用程序行为并添加自己的行为(最大限度地减少意外副作用的可能性),通知是可能的:

- (void)sendEvent:(NSEvent *)theEvent
{
    [super sendEvent:theEvent];
    if (theEvent.modifierFlags & NSCommandKeyMask) {
        if (theEvent.type == NSKeyUp) {
            [[NSNotificationCenter defaultCenter] postNotificationName:@"myKeyUp" object:theEvent];
        }
        if (theEvent.type == NSKeyDown) {
            [[NSNotificationCenter defaultCenter] postNotificationName:@"myKeyDown" object:theEvent];
        }
    }
}

然后添加适当的对象作为通知的观察者 .