Как сделать NSMenuItem серым?

Я пишу приложение на Swift, предназначенное для macOS Sierra.

У меня есть NSMenuItem, который я хотел бы сделать серым (чтобы пользователь даже не мог его выбрать).

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

Когда я устанавливаю для свойства isEnabled моего NSMenuItem значение false, это означает, что мое действие, связанное с пунктом меню, не вызывается (что хорошо), когда я выбираю этот пункт меню, но меню остается доступным для выбора.

Я бы хотел, чтобы он был выделен серым цветом и, очевидно, не мог быть выбран пользователем.


person BearOverflow    schedule 01.09.2017    source источник
comment
Вы хотите сделать его серым. Откуда? Контроллер представления? Оконный контроллер? делегат приложения? Синглтон?   -  person El Tomato    schedule 02.09.2017
comment
@ElTomato - это из моего AppDelegate в контексте обратного вызова уведомления (наблюдатель за NotificationCenter): я хочу, чтобы меню включалось/отключалось на основе новых значений, которые вызывали уведомление   -  person BearOverflow    schedule 02.09.2017
comment
Это не тот ответ, который я ищу. Кто публикует уведомление и как?   -  person El Tomato    schedule 02.09.2017
comment
@ElTomato Компонент A вызывает NotificationCenter.default.post() в ответ на изменение одного из его свойств (логического значения). Это делается в функции didSet(), прикрепленной к этому свойству. Мой AppDelegate является наблюдателем этого уведомления, и вызывается его обратный вызов. В обратном вызове я проверяю значение логического значения и устанавливаю MenuItem в соответствии с его значением: если true, я хочу, чтобы меню было включено и черное (поэтому можно было выбрать), а если false, я хочу, чтобы меню было отключено и выделено серым цветом (недоступно для выбора)   -  person BearOverflow    schedule 02.09.2017


Ответы (1)


Судя по документации, то, что вы делаете, звучит правильно.

Однако я реализую validateMenuItem в своем классе AppDelegate. Этот метод немного раздражает, потому что он вызывается для каждого пункта меню, при этом пункт меню передается в качестве параметра. Таким образом, вы должны включить параметр, посмотреть, является ли он пунктом меню, который вы хотите отключить, и вернуть false.

Здесь есть пример Objective-C: https://developer.apple.com/documentation/objectivec/nsobject/1518160-validatemenuitem

Пример Swift может выглядеть так:

override func validateMenuItem(_ menuItem: NSMenuItem) -> Bool {       
    switch menuItem.tag {
    case MenuItemTags.SignOut:
        return signOutEnabled()
    case MenuItemTags.CheckForUpdates:
        return updatesEnabled()
    default:
        return true
    }
}

Возможно, вы уже читали это, но здесь много подробностей: https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/MenuList/Articles/EnablingMenuItems.html

Однако, как я уже сказал, эта статья, похоже, указывает на то, что вы пытаетесь сделать это правильно, так что кто знает? Могу точно сказать, что мой способ работает.

person brindyblitz    schedule 01.09.2017