swift: Как меню радио? чтобы они были взаимоисключающими?

введите здесь описание изображенияЯ хочу получить меню радио, вот меню моего поколения

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

person 小弟调调    schedule 30.07.2014    source источник


Ответы (3)


Во-первых, решение:

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, компилятор должен знать, что оно имеет тип NSMenuItem. Это делается с помощью понижающего приведения в цикле for-in: as [NSMenuItem!], что, как я вижу, и есть то, что вы пытались сделать со строкой выше: var itemMore:NSMenuItem!. (Тем не менее, вы можете удалить это сейчас.) Вы правильно выбрали неявно развернутый необязательный элемент, поскольку menu.itemArray гарантированно не содержит нулевых значений.

Если вы этого не сделаете, компилятор будет рассматривать элемент меню как AnyObject, который имеет свойство типа NSURLSesionTaskState, также называемое «состоянием». Попытка установить для этого значение Int (что, по сути, является NSOnState/NSOffState) вызывает ошибку компилятора.

person Atomix    schedule 09.08.2014

Как насчет этого

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;
                }
            }
        }
    }
}
person xmkevinchen    schedule 09.08.2014

Я буду писать на Objective-C. Перевод на Swift зависит от вас.

for (NSMenuItem* item in [[sender menu] itemArray])
{
    if (item.action == sender.action)
        item.state = (item == sender) ? NSOnState : NSOffState;
}
person Ken Thomases    schedule 09.08.2014
comment
Ошибка компилятора swift 【'@lvalue $T9' не идентична 'NSURLSessionTaskState!' 】 - person 小弟调调; 09.08.2014
comment
Я не уверен, почему вы должны использовать itemMore.action() со скобками, в то время как sender.action без скобок нормально. Это может означать, что вам нужно выполнить itemMore.setState((itemMore == sender) ? NSOnState : NSOffState) вместо использования присваивания item.state. (Это сообщение об ошибке очень неясно. Я не знаю, почему оно вообще упоминает NSURLSessionTaskState.) - person Ken Thomases; 09.08.2014