这是我的解决方案,就像我的情况一样:
STEP 1. 子类 NSViewController 和覆盖-performKeyEquivalent(with:)
方法:
extension MyViewController {
override func performKeyEquivalent(with event: NSEvent) -> Bool {
switch event.modifierFlags.intersection(NSEvent.ModifierFlags.deviceIndependentFlagsMask) {
case [.command] where event.characters == "\r":
// do something, and....
// return a flag that we have handled this key-stroke combination
return true
default:
// otherwise unhandled (by return `false`)
return false
}
}
}
步骤 2. 设置您的控制器以观察本地事件:
class MyViewController: NSViewController {
// ...
// properties and methods...
// ...
override func viewDidLoad() {
super.viewDidLoad()
_ = NSEvent.addLocalMonitorForEvents(matching: .keyDown) { (event) -> NSEvent? in
// process the event and get the handled/unhandled flag;
let isHandled = self.performKeyEquivalent(with: event)
// stop dispatching this event if handled, or...
// dispatch it forward to next receiver if unhandled
return isHandled ? nil : event
}
}
// ...
}
我发现错误哔声是由您在块中分派事件后的后续调用之一触发的。因此,要使哔声静音,只需通过 return nil 停止调度它。
参考文档:
使用 +addLocal 安装一个事件监视器,该监视器在事件被 -[NSApplication sendEvent:] 分派之前接收事件。在这种情况下,您的块应该返回一个有效的 NSEvent(可能与传入的 NSEvent 相同,或者可能是新创建的 NSEvent)以导致事件被调度,或者它可能返回 nil 以停止事件的调度. 请注意,对于嵌套事件跟踪循环(例如控件跟踪、菜单跟踪或窗口拖动)消耗的事件,不会调用您的处理程序;只有通过 -[NSApplication sendEvent:] 分派的事件才会传递给您的处理程序。