NSMenuItem的setEnabled即使对于NSMenu将{autosablesItems设置为NO

时间:2015-11-30 23:00:29

标签: objective-c macos cocoa nsmenu nsmenuitem

我维护了一些遗留代码,当它被提前用10.8 SDK而不是10.7 SDK编译时,某些菜单项的一些关键等效快捷方式停止工作。我的假设是,这是因为那些菜单项处于禁用状态。不再工作的NSMenuItems是autoenablesItems设置为NO的子菜单的一部分(我通过属性检查器在xib中通过该子菜单确认了这一点,并通过查询[NSMenu autoenablesItems]以编程方式确认了这一点。它基本上出现了对[NSMenuItem setEnabled:]的调用无效,因为如果我在调用setEnabled后立即查询[NSMenuItem isEnabled]:YES,状态没有改变,它仍然为isEnabled返回NO。这里是一个片段代码与它生成的输出:

printf("DEBUG: Current state of menu item is ");
[nsMenuItem isEnabled] ? printf("enabled\n") : printf("DISABLED!\n");
printf("DEBUG: Current state of menu autoenablesItems is ");
[nsMenu autoenablesItems] ? printf("YES\n") : printf("NO\n");

[nsMenuItem setEnabled:YES];

printf("DEBUG: Current state of menu after setting it is ");
[nsMenuItem isEnabled] ? printf("enabled\n") : printf("DISABLED!\n");

输出:

DEBUG: Current state of menu item is DISABLED!
DEBUG: Current state of menu autoenablesItems is NO
DEBUG: Current state of menu after setting it is DISABLED!

我还尝试了子类化NSMenuItem并重写setEnabled以查看是否有另一个调用覆盖我的调用的setEnabled,但是没有其他调用通过setEnabled。

如果我点击子菜单的父菜单,那么它似乎会纠正状态并且这些NSMenuItems已启用,但它不会通过我的setEnabled代码来更改此状态。我尝试在启用的子类中添加一个观察者来尝试捕获在单击父菜单时将状态设置为启用的位置,但是由于观察者仅在我的调用中被触发,因此没有提供任何见解setEnabled实际上并没有改变状态。

从阅读Apple文档中我可以看出,只要在父菜单上将autoenablesItems设置为NO,NSMenuItem的setEnabled就可以正常工作,但在这种情况下似乎不起作用,我无法弄清楚原因。

在相同的代码中,如果我使用10.7 SDK进行编译(请注意:这实际上是代码库的旧版本,所以还有其他差异,但这个特定代码是相同的),我确实看到了调用setEnabled会更改NSMenuItem的状态。当它在10.7版本中输入此代码时,NSMenuItem已经处于启用状态,但我确实尝试将调用更改为setEnabled:NO以确认这是否实际上切换了isEnabled状态,并且它确实与10.8版本不同。

为什么这个没有在10.8工作的任何想法?我也试过10.9而且它也没有在那里工作。我已经无法尝试10.10或10.11了,因为还有一些其他代码需要更新,以便使用更新的SDK进行编译(同样,这是相当旧的遗留代码)。

2 个答案:

答案 0 :(得分:0)

不确定为什么SDK版本会很重要,但您是否检查过InterfaceBuilder中的菜单以确保它没有为“启用”状态设置绑定?这将是物品被神秘地禁用的另一种方式。

否则,菜单委托可能会从您的其他代码下替换菜单项,或明确禁用项目。还有一个NSMenuDelegate方法

- menuHasKeyEquivalent:forEvent:target:action:

在按下加速键的情况下会被特别调用,并且可以完全绕过菜单项的启用/禁用状态。

答案 1 :(得分:-1)

简单地使用它来启用/禁用菜单项

NSMenu *menu = [[NSMenu alloc] init];

添加禁用菜单项

[menu addItemWithTitle:@"DisableItem" action:nil keyEquivalent:@""];

添加启用菜单项

[menu addItemWithTitle:@"EnableItem" action:@selector(method:) keyEquivalent:@""];