NSCollectionView 不会接受关键事件

Dav*_*son 2 keydown first-responder nscollectionview

我有一个带有 3 个 NSTableViews 和 1 个 NSCollectionView 的窗口。集合视图显示图像。我希望能够选择其中一个图像并使用键盘删除键将其删除,但我无法让 collectionview 成为第一响应者。我可以选择任何 tableviews 并覆盖 keyDown 以接受键盘输入,但这不适用于 collectionview。我在其他地方使用 makeFirstResponder(_:) 强制关注集合视图,但在该应用程序中,窗口只有一个视图。对我做错了什么有任何想法吗?

小智 5

如果您可以在集合视图中选择图像或使用键盘上的箭头键在集合视图中导航 - 通常这意味着集合视图是 firstResponder。

所以尝试启用选择,检查是否启用了集合视图。

也有可能删除键是等效 键,请在此处阅读更多内容。如果是这样,您应该覆盖performKeyEquivalent(with: )方法以接收此类事件

此外, NSCollectionViewkeyDown(with: )方法不会将关键事件向上传递到响应者链。要在它的超级视图中处理此类事件,您应该通过调用self.nextResponder?.keyDown(with: event)您想要自己处理的此类事件在集合视图中覆盖它。


小智 5

为了扩展康斯坦丁的有效答案......

令人恼火的是,NSCollectionView 不会将未修改的按键事件传递到响应者链上 - 即使它本身不直接处理它们 - 就像删除键一样。

如果您需要“删除”键作为“文件/删除”菜单项的等效键,您只需在界面生成器中通过按该项目的“等效键”值中的“退格键”进行设置,然后创建NSCollectionView 的超类,并覆盖 keyDown - 就像在 Swift 4 中一样...

    override func keyDown(with event: NSEvent) {
    if let ascii = event.characters?.first?.unicodeScalars.first?.value, ascii == NSBackspaceCharacter || ascii == NSDeleteCharacter {
        nextResponder?.keyDown(with: event)
    } else {
        super.keyDown(with: event)
    }
}
Run Code Online (Sandbox Code Playgroud)

这样,菜单最终会收到事件,并执行“等效键”操作。所以你可以处理它,例如。在视图控制器中:

@IBAction func delete(_ sender: AnyObject) {
    // ... do whatever
}
Run Code Online (Sandbox Code Playgroud)