1

我很难理解 OS X 中的响应者链。

我有一个 NSTextView 子类,我希望它响应命令键并执行某些操作。我已经为我的问题创建了一个非常简单的演示。任何有兴趣的人只需几分钟的努力就可以看到。

创建一个新的 OS X 项目,这里是您唯一需要的附加代码。在 Swift 中创建一个名为 MyTextView 的新类(NSTextView 的子类)并将其粘贴到其中:

import Cocoa

class MyTextView: NSTextView {

    // listen for a command key
    override func performKeyEquivalent(theEvent: NSEvent) -> Bool {

        // if it's a cmd-equals, change the background
        if theEvent.characters == "=" && theEvent.modifierFlags.contains(.CommandKeyMask) {
            Swift.print(theEvent)
            self.backgroundColor = NSColor(calibratedRed: CGFloat(arc4random()) / CGFloat(UInt32.max),
                green: CGFloat(arc4random()) / CGFloat(UInt32.max),
                blue: CGFloat(arc4random()) / CGFloat(UInt32.max),
                alpha: 1.0)
            return true
        }
        return super.performKeyEquivalent(theEvent)
    }
}

现在在您的故事板中,将 2 个或更多 NSTextViews 放入同一个 contentView。在 Identity Inspector 下,告诉每个 NSTextView 它的类是 MyTextView(NSTextView 嵌套了一点:NSScrollView > NSClipView > NSTextView)。

运行项目。点击 cmd 等于。其中一个文本视图改变了它的背景颜色,但它不一定是拥有光标的那个,它正在接收所有其他按键。它不一定是从光标开始的那个。而且,如果您将光标放在不同的 textView 中,它仍然不会改变哪个响应命令键。

这是为什么?为什么接收键入的击键的文本视图与接收命令键的文本视图不同?显然,文本视图知道谁应该接收击键,因为打字有效。但是我的命令键交给了其他人。

4

1 回答 1

1

这是解决方案。MyTextView 需要测试是否是FirstResponder。如果是,它会消耗该事件。如果不是,则不是。

override func performKeyEquivalent(theEvent: NSEvent) -> Bool {

    if self.window?.firstResponder == self {
        // if it's a cmd-equals, change the background
        if theEvent.characters == "=" && theEvent.modifierFlags.contains(.CommandKeyMask) {
            Swift.print(theEvent)
            self.backgroundColor = NSColor(calibratedRed: CGFloat(arc4random()) / CGFloat(UInt32.max),
                green: CGFloat(arc4random()) / CGFloat(UInt32.max),
                blue: CGFloat(arc4random()) / CGFloat(UInt32.max),
                alpha: 1.0)
            return true
        }
    }
    return super.performKeyEquivalent(theEvent)
}
于 2016-02-02T04:58:22.203 回答