【问题标题】:How To Detect Which NSMenuItem Was Selected如何检测选择了哪个 NSMenuItem
【发布时间】:2018-08-23 00:56:03
【问题描述】:

鉴于我的 menuBar 应用程序在子菜单上有 3 个项目:

let delaySubMenu = NSMenu()

delaySubMenu.addItem(NSMenuItem(title: "5", action: #selector( setReminder(_:)), keyEquivalent: ""))
delaySubMenu.addItem(NSMenuItem(title: "10", action: #selector(setReminder(_:)), keyEquivalent: ""))
delaySubMenu.addItem(NSMenuItem(title: "15", action: #selector(setReminder(_:)), keyEquivalent: ""))

如何检测我的哪些 delaySubMenu 项目已被选中,而不为每个项目创建唯一的 setReminder 函数?

谢谢

【问题讨论】:

    标签: swift macos cocoa nsmenu nsmenuitem


    【解决方案1】:

    操作selector 将接收sender 对象,就像您使用Interface Builder 时一样。所以你的setReminder(_:) 选择器可以有签名:

    func setReminder(_ sender: Any) {
    // Coerce sender to NSMenuItem and use it to make your decisions
    }
    

    或:

    func setReminder(_ sender: NSMenuItem) {
    // Don't do any coercion work you don't need to do…
    }
    

    您还可以将NSMenuItemtag property 设置为您的延迟值。 tag 属性是 Int 类型,因此非常适合您的值。

    当您创建多个条目时,您可以使用for in 循环遍历arraydictionary,为每个条目创建一个新的NSMenuItem。因此,我们可以将您的原始代码更改为类似于此示例的内容,其中我使用了dictionary

    let delaySubMenu = NSMenu()
    let delays = ["5 Minutes" : 5, "10 Minutes" : 10, "15 Minutes" : 15] // This is a dictionary of String:Int
    
    for (titleKey, value) in delays {
        let menuItem = NSMenuItem(title: titleKey, action: #selector(setReminder(_:)), keyEquivalent: nil)
        menuItem.tag = value
        delaySubMenu.addItem(menuItem)
    }
    
    func setReminder(_ sender: NSMenuItem) {
        let delayValue = sender.tag // delayValue is a Int by inference from tag
    
        // Do something with your delay value
    }
    

    免责声明:这只是在浏览器中剪切和粘贴,因此可能需要一些调整才能真正起作用。

    【讨论】:

    • NSMenuItem 有什么比标签更可靠地识别它的呢?你肯定不是在建议他使用这个标题??
    • 不……我的意思不是直接将值存储在标签中……而是使用它来存储标识符……我想这并不像我应该说的那么清楚 - 我会更新
    • 谢谢,我可以使用第二个示例 'let someVar = sender.title' 来获取我需要的内容,但您可能想用一个完整的示例进行更新,我找不到太多关于coercion 并且不得不猜测一些事情。如果我使用sender: Any,我会将coercelet someVar = sender.title as NSMenuItem 类似吗?
    • 很抱歉,但我认为使用title 来识别这是一个糟糕的菜单项。这只是糟糕的做法。使用tag 或子类并给它一个属性。标签不需要需要“在整个应用程序中唯一”,因此这个答案的整个放置方式具有误导性。
    • @ian 和 @matt - 更新了创建 NSMenuItem 并使用 tag 存储值的示例……这比将 titleString 强制转换为安全得多Int
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多