在包含多个 NSTextFields 的 window 中捕获 space 键

Capture the space key in a window containing several NSTextFields

我有一个很大的 window,上面有许多 NSTextField 字段,我想截取 space 栏,即使任何文本字段都具有焦点,这样在任何时候按下 space 都会引起一个单独的动作。

子类化 NSTextField 并覆盖 -keyUp: 允许我检测到 space 键,但文本字段中仍插入空白。 -keyDown: 根本不触发。

对于 Return 和箭头键等其他键,我可以使用 control:textView:doCommandBySelector: 委托方法,但它不会与 space 栏一起触发。

NSTextView 有很多建议,但我发现 none NSTextField

如果您知道如何为 NSTextView 执行此操作,那么您就知道如何为 NSTextField 执行此操作,因为 NSTextField 使用称为 [=] 的 NSTextView 19=] 进行编辑。您可以获得 window 的默认字段编辑器,如下所示:

NSTextView* fieldEd = [myWindow fieldEditor: YES forObject: nil];

您还可以使用 window 委托来提供自定义字段编辑器。

所以你可能想看看 ReactiveCocoa

转到此 page 上的视频并查看 5:14 以查看与您可能喜欢的内容类似的内容。

ReactiveCocoa 可以挂接到您所有的文本字段中,然后任何时候 space 被击中时,信号处理程序都可以将其拾取。 (但是,可能比您想了解的要多)。

由于您要实现的行为处于 window 级别(或者可能是所有文本字段的祖先视图),您应该考虑实现 -performKeyEquivalent:在该级别而不是尝试在每个单独的文本字段中捕获 space 键。

在您的实施中,检查事件的 modifierFlags 以确保 none Control、Option 或 Command 被按下(假设您只想处理未修改的 space 按键)如果它的 charactersIgnoringModifiers 等于 @" "。如果是这样,做你想做的,然后 return YES 表明你已经处理了按键事件。否则,return NO 允许正常处理。

您尝试过添加事件监视器吗?您通过 NSEvent class 方法 addLocalMonitorForEventsMatchingMask(_:handler:) 创建它们,它们会为您提供指定事件的优先权。在您的情况下,您将为 keyDown 事件添加一个监视器,然后在关联的块中决定如何处理它们。在块的末尾,你可以 return 事件刚好到达,在这种情况下它会正常运行,你可以吞下事件(return nil),或者你可以修改通过创建一个新的事件对象并 returning 来代替该事件。这是一个例子:

// You can add monitors anywhere - I've chosen the AppDelegate for
// this simple example.
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
    [NSEvent addLocalMonitorForEventsMatchingMask:NSKeyDownMask
                                          handler:^NSEvent * (NSEvent * theEvent) {

          if (theEvent.keyCode == 49) {
              NSLog(@"swallowing spacebar");
              theEvent = nil;

          }

          return theEvent;
    }];
}