validateMenuItem 禁用特定的菜单项

validateMenuItem to disable specific menu items

我是 macOS XCode Obj-C 的新手,所以请多多包涵。我正在尝试使用 validateMenuItem 来禁用和启用特定的菜单项。

我目前正在努力禁用和启用*所有菜单项:

BOOL g_bEnableAllMenus = YES;

然后我使用 validateMenuItem

- (BOOL)validateMenuItem:(NSMenuItem *)item
{
    if( !g_bEnableAllMenus  )
        return NO;

    return YES;
}

为了测试,我在 awakeFromNib 中调用 g_bEnableAllMenus,它正确地禁用了我所有的菜单项。

- (void)awakeFromNib {
    g_bEnableAllMenus = NO; 
}

我现在要做的是这个场景:

我希望它在调用 g_bEnableAllMenus = YES/NO; 时禁用和启用所有菜单项,而不是 g_bEnableAllMenu 禁用和启用所有菜单项,除了名为 TestMenu 的菜单下的几个其他菜单项的列表。

然后我希望 TestMenu 下的其他菜单项列表用不同的 BOOL 单独控制:所以我可以单独启用和禁用此菜单项而不是通过 g_bEnableAllMenus 更改它 - 仅通过 g_bEnableTestMenu.

BOOL g_bEnableTestMenu = YES;

这就是我卡住的地方。我想我必须在 validateMenuItem 中使用 [item action] == @selector(TestMenuItem:) 的某种组合,所以当 g_bEnableTestMenu == NO 它禁用我的 TestMenu 下的所有菜单项(但不触及其他菜单项)。

然后当 g_bEnableAllMenus == NO 它仍然禁用我的所有菜单(就像现在正确的那样)但不包括我的 TestMenu。

根据我上面的评论,这里有一个更具体的答案。

您可以在菜单项上设置标签值以避免必须按 action/selector 进行匹配。如果您在代码中创建菜单项,只需直接设置 .tag 属性;在 .xib 布局中,将其设置在菜单项的主要属性选项卡上:

然后在您的验证处理程序中,您可以只检查标签的范围:

func validateUserInterfaceItem(_ item: NSValidatedUserInterfaceItem) -> Bool {
    if item.tag >= 1000 && item.tag <= 1100 {
        // return your test validation logic result
    } else {
        // return your normal validation result
    }
}

当然,您可以通过为测试菜单项标签范围最小值和最大值定义常量或使用其他数据结构(例如,测试项标签值的 CaseIterable 枚举)来改进此示例。您可能希望为共享验证逻辑的其他命令组使用标签,这些验证逻辑不易由 selectors/responder-chain.

确定