gpt4 book ai didi

cocoa - 方向键的 NSApplication 响应程序链

转载 作者:行者123 更新时间:2023-12-03 17:37:29 24 4
gpt4 key购买 nike

我的窗口中有一个 NSTextField 和 4 个具有等效键的菜单项 .

当选择文本字段并按箭头键时,我希望光标在文本字段中移动,但会执行相应的菜单项操作。

所以响应者链中肯定存在问题。为了找出问题所在,我观看了WWDC 2010 Session 145 – Key Event Handling in Cocoa Applications在此提到NSMenuItem KeyEquivalent space " " bug线程。


session 中按键(热键)的事件流程如下所示:

Event Flow



因此,我使用具有 keyEquivalent = K (只是任何普通键)的菜单项和具有 keyEquivalent = → (右箭头键)的菜单项检查了调用堆栈

K key event call stack Right arrow key event call stack

第一:K键事件调用栈;第二:右方向键事件调用栈

所以当按下箭头键时,事件会直接发送到 mainMenu.performKeyEquivalent,但实际上应该发送到 keyWindow 对吗?

这是为什么?如何修复此行为,以便我的 NSTextFieldmainMenu 之前接收箭头键事件?

最佳答案

关于调用堆栈差异的有趣观察。由于箭头键在导航中发挥着最重要的作用,因此它们的处理方式可能与其他键不同,就像您在 NSMenuItem KeyEquivalent space " " bug 中看到的那样。线。同样,这是 AppKit 负责处理幕后一切的情况之一,让您的生活在 99.9% 的情况下变得更轻松。

当文本字段获得焦点时,您可以通过按 k 来查看行为的实际差异。与箭头不同,菜单项的按键等效项不会被触发,输入会直接进入控件。

根据您的情况,您可以使用 NSMenuItemValidation协议(protocol)覆盖启用或禁用特定菜单项的默认操作。据我所知,这可以进入链中的任何响应者,例如 View Controller 、窗口或应用程序。因此,当窗口的第一响应者是文本字段或使用这些事件正确操作的任何其他控件时,您可以在一个位置启用/禁用菜单项。

extension ViewController: NSMenuItemValidation {
func validateMenuItem(_ menuItem: NSMenuItem) -> Bool {
// Filter menu item by it's assigned action, just as an exampe.
if menuItem.action != #selector(ViewController.menuActionLeftArrowKey(_:)) { return true }
Swift.print("Validating menu item:", menuItem)
// Disable the menu item if first responder is text view.
let isTextView = self.view.window?.firstResponder is NSTextView
return !isTextView
}
}

这将在显示菜单之前调用,以更新项目状态,在调用菜单项键等效项之前调用,以检查操作是否需要发送,并且可能在其他情况下,当 AppKit 需要检查项目状态时 - 可以我脑子里想不出任何东西。

附注上面的第一响应者检查是针对 NSTextView 而不是 NSTextField 进行的,here's为什么。

关于cocoa - 方向键的 NSApplication 响应程序链,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61839795/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com