swift:如何单选菜单?使它们相互排斥?

Posted

技术标签:

【中文标题】swift:如何单选菜单?使它们相互排斥?【英文标题】:swift:How radio menu?so that they are mutually exclusive? 【发布时间】:2014-07-30 16:52:38 【问题描述】:

我要实现单选菜单,这里是我这一代的菜单

subMenu.addItemWithTitle("Item001", action: Selector("testAction:"), keyEquivalent: "\(code)")
subMenu.addItemWithTitle("Item002", action: Selector("testAction:"), keyEquivalent: "\(code)")
subMenu.addItemWithTitle("Item003", action: Selector("testAction:"), keyEquivalent: "\(code)")
subMenu.addItemWithTitle("Item004", action: Selector("testAction:"), keyEquivalent: "\(code)")
subMenu.addItemWithTitle("Item005", action: Selector("testAction:"), keyEquivalent: "\(code)")
subMenu.addItemWithTitle("Item006", action: Selector("testAction:"), keyEquivalent: "\(code)")

如何单选菜单?

func testAction(sender: NSMenuItem)
    sender.state = Int(!Bool(sender.state))
    if(sender.action == Selector("testAction:"))
        var itemMore:NSMenuItem!
        for itemMore:AnyObject in sender.menu.itemArray 
            if (itemMore.action() == sender.action)
                itemMore.state = (itemMore == sender) ? NSOnState : NSOffState;
            
        
    

【问题讨论】:

【参考方案1】:

一、解决办法:

func testAction(sender: NSMenuItem)
    sender.state = Int(!Bool(sender.state))
    if(sender.action == Selector("testAction:"))
        for itemMore in sender.menu.itemArray as [NSMenuItem!]
            if (itemMore.action == sender.action)
                itemMore.state = (itemMore == sender) ? NSOnState : NSOffState;
            
        
    

现在解释: 要设置 menuItem 的 state 属性,编译器必须知道它是 NSMenuItem 类型。这是通过在 for-in 循环中向下转换来完成的:as [NSMenuItem!],正如我所看到的,这就是您在上面的行中尝试的:var itemMore:NSMenuItem!。 (不过,您现在可以删除它。)您正确地选择了一个隐式展开的可选项,因为 menu.itemArray 保证不包含 nil 值。

如果你不这样做,编译器会将 menuItem 视为 AnyObject,它恰好有一个 NSURLSesionTaskState 类型的属性,也称为“状态”。尝试将其设置为 Int(本质上就是 NSOnState/NSOffState)会引发编译器错误。

【讨论】:

【参考方案2】:

这个怎么样

func testAction(sender: NSMenuItem)
    sender.state = Int(!Bool(sender.state))
    if(sender.action == Selector("testAction:")) 
        var itemMore:NSMenuItem!
        for itemMore:AnyObject in sender.menu.itemArray 
            if let menuItem = itemMore as? NSMenuItem   // -- need to downcast first
                if (menuItem.action == sender.action)
                    menuItem.state = (menuItem == sender) ? NSOnState : NSOffState;
                
            
        
    

【讨论】:

【参考方案3】:

我会用 Objective-C 来写。翻译成 Swift 由你决定。

for (NSMenuItem* item in [[sender menu] itemArray])

    if (item.action == sender.action)
        item.state = (item == sender) ? NSOnState : NSOffState;

【讨论】:

swift 编译器错误【'@lvalue $T9' is not same to 'NSURLSessionTaskState!' 】 我不知道为什么你必须使用带括号的itemMore.action(),而不带括号的sender.action 很好。这可能意味着您需要执行itemMore.setState((itemMore == sender) ? NSOnState : NSOffState) 而不是对item.state 使用赋值。 (那个错误信息很不清楚。我不知道为什么它提到了NSURLSessionTaskState。)

以上是关于swift:如何单选菜单?使它们相互排斥?的主要内容,如果未能解决你的问题,请参考以下文章

Windows 核心音频 API 中的 ERoles 枚举值代表啥?它们是相互排斥的吗?

D3.js 强制有向图,通过使边缘相互排斥来减少边缘交叉

如何在 Tkinter 中将单选按钮添加到子菜单

将单选按钮关联到各个组

进程同步与相互排斥:POSIX有名信号量

Xcode:如何创建 dSym 并仍然剥离符号?