无法在NSMenuItem上设置setEnabled:NO

23

我已经对 NSMenu 进行了子类化,并通过 Interface Builder 连接了一堆 NSMenuItem。通过调试器进行测试,我确信它们已经被初始化。

该菜单设置为不自动启用项目。但是,当我将任何一个 NSMenuItem 的 [myMenuItem setEnabled:NO] 设置为禁用时,它们仍然处于启用状态。即使我在 NSMenu 子类中调用 [self update]

我漏掉了什么?


嘿,把你的解决方案发布为答案,然后你可以在几天后接受它。 - paulmelnikow
8个回答

78

我遇到了同样的问题,所以我想发布我的解决方案。NSMenu自动启用NSMenuButtons,因此我们必须覆盖它。

在IB中:

您应该取消选择“自动启用项目”

或者编程方式:

// Disable auto enable
[myMenu setAutoenablesItems:NO];

// Test it
[myMenuButton setEnabled:NO];
[myMenuButton setEnabled:YES];

8年过去了,这个答案仍然是相关的。 - Don

12

在一位同事的帮助下,我解决了这个问题,所以在这里发布它,以便其他遇到同样问题的人参考。

你应该将NSMenu子类设置为自动启用项目(默认行为),然后在NSMenu子类中实现此方法。

- (BOOL)validateMenuItem:(NSMenuItem *)menuItem {
    return [menuItem isEnabled];
}

11

enter image description here

你需要在最近的父级NSMenu上取消选中自动启用项目

7

您可以在不使用子类化的情况下解决这个问题。

如果您只需要标准菜单+一些自定义的 NSMenuItem,并且希望在您的控件上将其禁用,那么您可以:

  1. 添加一个更多的菜单节点 - 只需从对象库中拖放 子菜单菜单项 到您的菜单中。

  2. 将您想要管理的所有 NSMenuItems 添加到此新菜单节点中。

  3. 打开新菜单节点的属性检查器,并关闭自动启用项目选项:

    Auto Enables Items

  4. 配置菜单和项的任何其他选项。

现在您可以编写如下代码:

@property (weak) IBOutlet NSMenuItem *hidePlateMenuItem;
...
[self.hidePlateMenuItem setEnabled:NO];

并且它将能够很好地运行。

5

回应itsdavyh的提问,如果菜单项位于一个或多个子菜单中,则只需在菜单项的子菜单上取消“自动启用项目”属性,而不必在任何其他父菜单上这样做。


2

我尝试了所有这些解决方案,但最终我找到了真正的问题,这对我来说也更有意义。 这也是处理禁用nsmenuitem的最简单方法,无需子类化或编写代码。 在成为菜单本身的子项之前,nsmenuitem是主项的子项,例如“另存为...”是“文件”的子项。只需选择父项目(在此示例中为“文件”),并在菜单检查器面板中关闭“自动启用菜单项”,就可以了!


1

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

0
尝试从不同的位置调用[myMenuItem setEnabled:NO],并确保它发生在包含菜单的nib加载之后。也许可以在子类化的NSMenu的awakeFromNib中直接执行此操作。

我进行了一些快速测试,发现awakeFromNib总是在[myMenuItem setEnabled:NO]之前运行。正如您建议的那样,我尝试在awakeFromNib中更新菜单项,但也没有任何效果。 - Christoffer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接