Question

enter image description here I want to achieve radio menu,Here is my generation's menu

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)")

enter image description here How radio menu ?

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;
            }
        }
    }
}
Was it helpful?

Solution

First, the solution:

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;
            }
        }
    }
}

Now the explanation: To set the menuItem's state property the compiler must know that it is of type NSMenuItem. This is done via downcasting in the for-in loop: as [NSMenuItem!], which as I can see is what you attempted with the line above:var itemMore:NSMenuItem!. (You can remove that now, though.) You rightly chose an implicitly unwrapped optional, since menu.itemArray is guaranteed to not contain nil values.

If you don't do this, the compiler will treat the menuItem as AnyObject, which happens to have a property of type NSURLSesionTaskState which is also called 'state'. Attempting to set this to an Int (which is essentially what NSOnState/NSOffState is) raises the compiler error.

OTHER TIPS

How about this

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;
                }
            }
        }
    }
}

I'll write in Objective-C. Translating to Swift is up to you.

for (NSMenuItem* item in [[sender menu] itemArray])
{
    if (item.action == sender.action)
        item.state = (item == sender) ? NSOnState : NSOffState;
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top