I an new to macOS XCode Obj-C so bear with me. I am trying to use validateMenuItem
to disable and enable specific menu items.
I currently have this working to disable and enable *all menu items:
BOOL g_bEnableAllMenus = YES;
and then I am using the validateMenuItem
- (BOOL)validateMenuItem:(NSMenuItem *)item
{
if( !g_bEnableAllMenus )
return NO;
return YES;
}
To test, I am calling g_bEnableAllMenus
in awakeFromNib
and it is disabling all my menu items correctly.
- (void)awakeFromNib {
g_bEnableAllMenus = NO;
}
What I am trying to do now is this scenario:
Instead of g_bEnableAllMenu
s disabling and enabling ALL menu items when g_bEnableAllMenus = YES/NO;
is called, I want it to disable all menu items EXCEPT a list of several other menuItems under a menu called TestMenu.
Then I want this list of other menu items under TestMenu separately controlled with a different BOOL: so I can enable and disable this menu item separately and not have it changed by g_bEnableAllMenus
- only by g_bEnableTestMenu
.
BOOL g_bEnableTestMenu = YES;
There is where I am stuck. I think I have to use some combination of [item action] == @selector(TestMenuItem:)
in validateMenuItem
so when g_bEnableTestMenu == NO
it disables all menu items under my TestMenu (but doesn't touch other menu items).
Then when g_bEnableAllMenus == NO
it still disables all my menus (as it correctly does now) but excludes my TestMenu.
Here's a more concrete answer based on my comment above.
You can set a tag value on a menu item to avoid having to match by action/selector. If you're creating the menu items in code just set the .tag property directly; in an .xib layout set it on the main properties tab of the menu item:
Then in your validation handler you can just check the range of the tag:
func validateUserInterfaceItem(_ item: NSValidatedUserInterfaceItem) -> Bool {
if item.tag >= 1000 && item.tag <= 1100 {
// return your test validation logic result
} else {
// return your normal validation result
}
}
Of course you could improve this sample by defining constants for your test-menu-item tag range min and max, or with other data structures (e.g. a CaseIterable enum of test-item tag values). You might want to use tags for other groups of commands that share validation logic that isn't readily determined by selectors/responder-chain.