NSMenuItem not being enabled?

9.7k views Asked by At

I have an NSMenuItem called history which resides in a NSMenu called menu. When my program starts history doesn't have a submenu so its disabled. Then at some point, I need a submenu for history, so I create it, make it a submenu of history. An arrow appears beside history which tells me that the submenu is there. But history is still disabled. I have tried setEnabled but doesn't work. Please help. Here my code:

This is when I create my menu, and history as you can see an NSMenuItem in menu.

    menu = [[NSMenu alloc] initWithTitle:@"Menu"];
[[menu addItemWithTitle:@"History" action:nil keyEquivalent:@""] setTarget:self];
[[menu addItemWithTitle:@"Settings" action:@selector(loadSettings:) keyEquivalent:@""] setTarget:self];
[[menu addItemWithTitle:@"Quit" action:@selector(terminateApp:) keyEquivalent:@""] setTarget:self];

At this point, history is disabled (greyed out). Then somewhere in the program I need to have a submenu for history so:

        if (historyMenu == nil) {
        historyMenu = [[NSMenu alloc] initWithTitle:@"Lyrics history"];
        [menu setSubmenu:historyMenu forItem:[menu itemWithTitle:@"History"]];
    }

I now see an arrow beside history, but it's still greyed out.

Please help, I have been trying to figure this out for last 2 hours. Thanks.

3

There are 3 answers

1
Jon Steinmetz On

You are setting the target but have a nil action. Try not setting the target. This may leave it enabled all the time in which case you may have to manually enable or disable the menu item.

Here is the documentation on how menu items get enabled.

0
Adam Johns On

I had to override the validateMenuItem method to return true:

override func validateMenuItem(menuItem: NSMenuItem) -> Bool {
    return true
}

It didn't actually use the validation method until I set target to self though like you did with

menu.addItemWithTitle("An Item", action: #selector(itemPressed), keyEquivalent: "")?.target = self
0
Andres Canella On

macOS will handle the enabled state automatically based on it is being handled or not. So if you are setting an action you also need to set the target of the action.

let menu = NSMenu()
let itemPress = menu.addItem(withTitle: "some name..", action: #selector(press), keyEquivalent: "")
itemPress.target = self

and taget:

@objc func press() {
    print("pressed...")
}