Cannot seem to setEnabled:NO on NSMenuItem

2020-06-30 07:15发布

I have subclassed NSMenu and connected a bunch of NSMenuItem's via Interface Builder. I have tested via the debugger to see that they really get initialized.

The menu is set to not auto enable items. Still when I set any of my NSMenuItem's to [myMenuItem setEnabled:NO] they continue to be enabled. Even if I call [self update] from within the NSMenu subclass.

What am I missing?

8条回答
Juvenile、少年°
2楼-- · 2020-06-30 07:30

Had the same issue, so I thought I'd post my solution. NSMenu auto enables NSMenuButtons, so we have to override that.

In IB:

You should uncheck "Auto Enables Items"

Or programmatically:

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

// Test it
[myMenuButton setEnabled:NO];
[myMenuButton setEnabled:YES];
查看更多
别忘想泡老子
3楼-- · 2020-06-30 07:33

Adding to the response of itsdavyh, if the menu item is located inside one or more submenus you only have to uncheck the 'Auto enables items'-property on the submenu of the menu item and not on any other parentmenus.

查看更多
Evening l夕情丶
4楼-- · 2020-06-30 07:33

You can solve this problem without subclassing.

If only you need is standard menu + some custom NSMenuItems that can be disabled on your control, than you can just:

  1. Add one more menu node - just drag and drop Submenu Menu Item from Object library to your menu.

  2. Add all NSMenuItems you want to manage to this new Menu node.

  3. Open Attributes inspector for your New Menu node, and switch off Auto Enables Items option:

    Auto Enables Items

  4. configure any other options of your menu & items.

Now you can write a code like:

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

and it will works well.

查看更多
三岁会撩人
5楼-- · 2020-06-30 07:35

I solved it with the help of a colleague, so I post it here for others that experience the same issue.

You should set your NSMenu-sublass to auto-enable items (default behaviour) and then implement this method in the NSMenu-sublass.

- (BOOL)validateMenuItem:(NSMenuItem *)menuItem {
    return [menuItem isEnabled];
}
查看更多
何必那么认真
6楼-- · 2020-06-30 07:36

I tried all these solution but finally i found the real problem that also make more sense to me. It also is the simplest way to handle disabled nsmenuitem that no needs to subclass or do code. The nsmenuitem before to be child of menu itself is child of the main item for example "Save as..." is child of "File". Just select the parent item (in this example is File) and set off "auto enable menu items" in the menu ispector panel, and here you go!

查看更多
家丑人穷心不美
7楼-- · 2020-06-30 07:44

Swift 3 answer:

I have a submenu item under the standard "View" menu called "Enable System Setup On Launch". I use the function below to enable or disable the menu item. Note: the view menu does need the "Auto Enable Items" in IB to be turned off.

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
        }
    }
}
查看更多
登录 后发表回答