如何创建一个包含 NSMenuItem 的 NSMenu,该 NSMenuItem 仅在按住键盘修饰键时出现?

如何解决如何创建一个包含 NSMenuItem 的 NSMenu,该 NSMenuItem 仅在按住键盘修饰键时出现?

我想创建一个 NSMenu,其中包含一个认隐藏的 NSMenuItem,并且仅在用户按住键盘修改键时才会出现。

基本上,我正在寻找与 Finder 的“Go”菜单中的“Library”选项相同的行为:

不按住Option (⌥):

enter image description here

同时持有期权(⌥):

enter image description here


我已经尝试使用 [NSEvent addGlobalMonitorForEventsMatchingMask: handler:] 安装密钥侦听器,通过设置 NSMenuItem 属性以编程方式隐藏和取消隐藏 hidden。这种方法有效,但问题是当 NSMenu 打开时隐藏/取消隐藏不起作用。显然,NSMenu 在打开时完全接管了事件处理循环,从而阻止了键侦听器的工作。
我可能可以使用 CGEventTap 在 NSMenu 打开时仍然接收事件,但这似乎完全是矫枉过正。

我发现的另一个与我想要的类似的东西是 NSMenu 的“alternate”机制。但我只能让它切换 NSMenuItems,而不是隐藏/取消隐藏它们。

任何帮助将不胜感激。谢谢!

解决方法

假设您的仅选项菜单项的操作是(在 Swift 中)performOptionOnlyMenuItem(_:),其目标是您的 AppDelegate

  • 您需要做的第一件事是确保 AppDelegate 符合 NSMenuItemValidation 协议。

  • 您需要做的第二件事是实现 validateMenuItem(_:) 方法,并让它检查菜单项是否发送 performOptionOnlyMenuItem(_:) 操作。如果是,则根据当前是否按下选项键来设置项目的 isHidden 属性。

如果您不需要验证任何其他菜单项,代码可以如下所示:

extension AppDelegate: NSMenuItemValidation {
    func validateMenuItem(_ menuItem: NSMenuItem) -> Bool {
        switch menuItem.action {
        case #selector(performOptionOnlyMenuItem(_:)):
            let flags = NSApp.currentEvent?.modifierFlags ?? []
            menuItem.isHidden = !flags.contains(.option)
            return true
        default:
            return true
        }
    }
}

如果操作被发送到某个其他目标,您需要在该目标上实施验证(包括协议一致性)。每个菜单项仅由项的目标验证。

,

我找到了一个完美的解决方案!

  1. 在您想要隐藏的 NSMenuItem 上,将 alternate 属性设置为 YES,并将 keyEquivalentModifierMask 属性设置为您想要取消隐藏该项目。

  2. 在您的 NSMenu 中,就在要隐藏的 NSMenuItem 之前,插入另一个高度为 0 的 NSMenuItem。 >

    在 Objc 中,您可以像这样创建一个高度为 0 的 NSMenuItem

    NSMenuItem *i = [[NSMenuItem alloc] init];
    i.view = [[NSView alloc] initWithFrame:NSZeroRect];
    

可隐藏的 NSMenuItem 现在将“替代”它前面的零高度 NSMenuItem。默认情况下将显示零高度项目,但是当您按住您指定的键盘修饰符时,零高度项目将与可隐藏项目换出。由于零高度项是不可见的,因此具有取消隐藏可隐藏项的效果。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?