【问题标题】:Unwanted beep when a key is hit按键时发出不需要的蜂鸣声
【发布时间】:2019-09-16 16:28:21
【问题描述】:

我有一个接受键输入的自定义视图,它在 NSScrollView 内。我已将acceptsFirstResponder 设置为yes,它正在成功接受keyDown。但是每次我敲击一个键,我都会听到一声哔哔声。我确定还需要其他东西,但不记得是什么了。请帮忙。

-(void)keyUp:(NSEvent *)theEvent{

NSLog(@"is first responder %i", self.window.firstResponder == self);

switch (theEvent.keyCode) {
    case KeyCodeEnumBackspace:
    case KeyCodeEnumDelete:
    {
        if (self.scheduleControl.selectedEvent) {
            [self.scheduleControl deleteEvent:self.scheduleControl.selectedEvent];
        }
    }
        break;

    default:
        break;
}
   }

【问题讨论】:

  • 你在 NSView 的初始化代码中调用了[self becomeFirstResponder] 吗?
  • 不,当我单击控件时,它会成为第一响应者。但只是为了确保我检查了上面的代码是否是第一响应者。是的。

标签: cocoa nsview nsresponder


【解决方案1】:

知道了。哔声发生在keyDown,而不是KeyUp。要删除哔声,我需要处理它,一个空的实现就足够了。关键是传给super

- (void)keyDown:(NSEvent *)theEvent {

}

- (void)keyUp:(NSEvent *)theEvent {
    switch (theEvent.keyCode) {
        case KeyCodeEnumBackspace:
        case KeyCodeEnumDelete:
            if (self.scheduleControl.selectedEvent) {
                [self.scheduleControl deleteEvent:self.scheduleControl.selectedEvent];
            }
            break;
        default:
            break;
    }
}

【讨论】:

    【解决方案2】:

    这是我的解决方案:

    步骤 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:] 分派的事件才会传递给您的处理程序。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-09-29
      • 2012-11-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多