【问题标题】:Prevent 'not allowed' beep after keystroke in NSView在 NSView 中击键后防止“不允许”蜂鸣声
【发布时间】:2021-03-03 06:35:36
【问题描述】:

在我的 Mac 应用程序中,我通过 NSView 中的 keyUp 函数覆盖并接受某些击键,这并不意味着接受击键。

当一个键被按下时,keyUp 函数被调用,我确实处理了击键,甚至没有调用super keyUp:,一切正常,除了它也使默认值'当你在不应该按的地方按下一个键时会发出 doonk 的声音。

有什么方法可以表明击键被处理和接受,并且我不需要哔声告诉用户它不是?

【问题讨论】:

    标签: objective-c macos


    【解决方案1】:

    我认为(但不是 100% 确定,我这样做已经有一段时间了)您还需要覆盖 NSView 和/或 NSResponder performKeyEquivalent: 方法。在那里,您将返回一个 YES 以向调用者表明您确实处理了该事件。

    这样可以防止“dooonk”的声音发生。

    【讨论】:

    • 谢谢!只需将我的if 语句从我的keyUp: 函数复制并粘贴到这个函数中,然后添加returns。 :)
    • 在没有子类化的情况下有没有办法摆脱这种声音?
    • 我想澄清一下,您需要将您的代码从 keyDown: 或等效代码放入 performKeyEquivalent: (即替换其他方法)。此外,如果您使用flagsChanged: 方法来检测 CMD 之类的键,那么您需要继续使用flagsChanged:
    • 有一个优雅的解决方案是,如果我们已经处理了击键动作,我们不应该调用 super.keyDownsuper.keyUp
    【解决方案2】:

    您可能想要使用moveUp: 操作,而不是使用keyUp:,因为它消除了确定要处理哪个键的所有麻烦。也有类似命名的 down 例程和各种用于处理选择的移动等。

    有关这方面的更多文档,请参阅Cocoa Event-Handling Guide,尤其是“处理键盘操作和插入文本”,其中讨论了这些命令在“处理文本的其他应用程序”中的使用。

    特别是,使用这些操作的另一个好处是它可以避免任何键解释或特殊键盘和键盘布局的问题。

    【讨论】:

    • 整个问题在于我没有使用NSTextViews,并且自定义对象不是文本体,而是图像和其他控件之类的东西,我需要像Delete,Cmd + C这样的击键等,而不是鼠标拖动和箭头键。
    • 我不确定 NSTextView 与任何事情有什么关系。我在许多是 NSView 的直接子类的视图上使用这种技术,它们工作正常。各种 move*: 动作是作为默认 NSView 响应者链的一部分实现的,我很确定任何接受的视图都会收到这些动作。事实上,我有许多出货产品在没有 NSTextView 的情况下做到这一点。
    • 但是move*:的各种动作只针对方向键,我还需要其他的键和组合。
    • 好的,显然我在这方面误读了您的原始注释。您可能想要覆盖 keyDown: 而不是 keyUp: (或同样)。 keyDown: 是在 OS 中完成大部分处理的地方,也就是调用 translateKeyEvents: 之类的地方。 keyUp: 例程确实适用于您在按键关闭时监控状态的情况(您可以这样做,但哔哔声很可能发生在 keyDown:)。
    • 我试过了,覆盖 keyDown: 而不调用 super 也可以防止发出哔哔声,但我仍然发现覆盖 performKeyEquivalent: 更优雅。为keyDown: 方法+1 :)
    【解决方案3】:

    接受的答案可能会解决问题,但我想建议一种更正确的方法来解决问题:)

    使用keyUp:keyDown: 完全没问题,但最重要的是,您的视图还必须遵循AppKit 响应者模式(您可以在official documentation 上了解有关NSResponder 的更多信息)。

    在您的情况下,视图需要将自己作为事件链中的有效第一响应者发出信号。假设您有一个NSView 子类,您将需要实现以下方法:

    @implementation MyNSView
    
    //...
    
    - (BOOL)acceptsFirstResponder {
        return YES;
    }
    
    @end
    

    【讨论】:

      【解决方案4】:

      在我的情况下,performKeyEquivalent 没有捕获 Enter 键。哔声在keyDown 事件中触发。此 Swift 代码可防止在处理 Enter 键时发出哔哔声:

      override func keyDown(with event: NSEvent) {
          if event.keyCode != 36 {
              super.keyDown(with: event)
          }
      }
      
      override func keyUp(with event: NSEvent) {
          if event.keyCode == 36 {
              // Do your thing
          }
      }
      

      【讨论】:

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