我已经对 NSMenu
进行了子类化,并通过 Interface Builder 连接了一堆 NSMenuItem
。通过调试器进行测试,我确信它们已经被初始化。
该菜单设置为不自动启用项目。但是,当我将任何一个 NSMenuItem 的 [myMenuItem setEnabled:NO]
设置为禁用时,它们仍然处于启用状态。即使我在 NSMenu 子类中调用 [self update]
。
我漏掉了什么?
我已经对 NSMenu
进行了子类化,并通过 Interface Builder 连接了一堆 NSMenuItem
。通过调试器进行测试,我确信它们已经被初始化。
该菜单设置为不自动启用项目。但是,当我将任何一个 NSMenuItem 的 [myMenuItem setEnabled:NO]
设置为禁用时,它们仍然处于启用状态。即使我在 NSMenu 子类中调用 [self update]
。
我漏掉了什么?
我遇到了同样的问题,所以我想发布我的解决方案。NSMenu自动启用NSMenuButtons,因此我们必须覆盖它。
在IB中:
或者编程方式:
// Disable auto enable
[myMenu setAutoenablesItems:NO];
// Test it
[myMenuButton setEnabled:NO];
[myMenuButton setEnabled:YES];
在一位同事的帮助下,我解决了这个问题,所以在这里发布它,以便其他遇到同样问题的人参考。
你应该将NSMenu子类设置为自动启用项目(默认行为),然后在NSMenu子类中实现此方法。
- (BOOL)validateMenuItem:(NSMenuItem *)menuItem {
return [menuItem isEnabled];
}
您可以在不使用子类化的情况下解决这个问题。
如果您只需要标准菜单+一些自定义的 NSMenuItem
,并且希望在您的控件上将其禁用,那么您可以:
添加一个更多的菜单节点 - 只需从对象库中拖放 子菜单菜单项 到您的菜单中。
将您想要管理的所有 NSMenuItems 添加到此新菜单节点中。
打开新菜单节点的属性检查器,并关闭自动启用项目选项:
配置菜单和项的任何其他选项。
现在您可以编写如下代码:
@property (weak) IBOutlet NSMenuItem *hidePlateMenuItem;
...
[self.hidePlateMenuItem setEnabled:NO];
回应itsdavyh的提问,如果菜单项位于一个或多个子菜单中,则只需在菜单项的子菜单上取消“自动启用项目”属性,而不必在任何其他父菜单上这样做。
我尝试了所有这些解决方案,但最终我找到了真正的问题,这对我来说也更有意义。 这也是处理禁用nsmenuitem的最简单方法,无需子类化或编写代码。 在成为菜单本身的子项之前,nsmenuitem是主项的子项,例如“另存为...”是“文件”的子项。只需选择父项目(在此示例中为“文件”),并在菜单检查器面板中关闭“自动启用菜单项”,就可以了!
Swift 3答案:
我在标准的“视图”菜单下有一个名为“启动时启用系统设置”的子菜单项。我使用以下功能来启用或禁用该菜单项。注意:视图菜单需要在IB中关闭“自动启用项目”。
func enableSystemSetupMenuItem(enabled:Bool) {
//set view menu item to enabled: value
//requires "Auto Enable Items" of "View" menu item to be turned off in IB
//because "View" menu is now turned off for "Auto Enable" we have to handle all
//of the "View" menu items ourselves
//just to avoid operating on menu separators I set all other menu items to TAG = -1
let main = NSApplication.shared().menu?.item(withTitle: "View")
let subMenuItems = main?.submenu?.items
for item in subMenuItems! {
if item.title == "Enable System Setup On Launch" {
item.isEnabled = enabled
} else if item.tag == -1 {
item.isEnabled = true
}
}
}
[myMenuItem setEnabled:NO]
,并确保它发生在包含菜单的nib加载之后。也许可以在子类化的NSMenu的awakeFromNib
中直接执行此操作。awakeFromNib
总是在[myMenuItem setEnabled:NO]
之前运行。正如您建议的那样,我尝试在awakeFromNib
中更新菜单项,但也没有任何效果。 - Christoffer