如何在打开时更新 NSMenu?

Posted

技术标签:

【中文标题】如何在打开时更新 NSMenu?【英文标题】:How to update NSMenu while it's open? 【发布时间】:2012-04-25 13:45:37 【问题描述】:

我有一个动态添加 NSMenuItems 的 NSMenu。 NSMenu 在保持打开状态时未正确刷新。我在NSEventTrackingRunLoopModes调用NSMenu更新方法。

我已经实现了以下方法来更新 NSMenu。

- (void)menuNeedsUpdate:(NSMenu *)menu 
for (NSInteger index = 0; index < count; index++)
    [self menu:menu updateItem:[menu itemAtIndex:index] 
                       atIndex:index 
                  shouldCancel:NO];


- (BOOL)menu:(NSMenu *)menu updateItem:(NSMenuItem *)item atIndex:(NSInteger)index shouldCancel:(BOOL)shouldCancel`

- (NSInteger)numberOfItemsInMenu:(NSMenu *)menu

【问题讨论】:

我也有类似的问题。我想在打开时更新 NSMenu,具体取决于用户是否按下选项键。当产品菜单打开并按下选项键时,我需要 Xcode 的行为。这可以通过内置的 NSMenu 方法来完成吗? 【参考方案1】:

更新NSEventTrackingRunLoopMode 中的菜单项解决了这个问题。

【讨论】:

【参考方案2】:

我在计时器中动态填充菜单项,而 NSMenu 在打开时没有更新。

确保在相应的运行模式下触发计时器:

[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];

您现在可能只能在 NSDefaultRunLoopMode 上触发它。

【讨论】:

我尝试过使用 NSRunLoopCommonModes,但在打开时仍然出现菜单刷新问题【参考方案3】:

你遗漏了一堆代码。但是,您不应该拨打-menu:updateItem:atIndex:shouldCancel:。这是你应该实现的方法,框架应该调用它。

另外,通常你只需要实现-menuNeedsUpdate: 或者这两个-numberOfItemsInMenu:-menu:updateItem:atIndex:shouldCancel:。实现所有三个没有多大意义。如果您可以立即构建菜单,则可以实施前者。如果构建菜单需要一些时间,则实现后两者。

最后,所有这些方法都被记录为“当菜单即将显示时”。在菜单打开时他们没有被重复调用,我并不感到非常惊讶。

如果您知道菜单需要更新,您可以尝试调用-[NSMenu update]。这可能会引发它调用您的委托方法。我很确定您也可以只调用 NSMenuNSMenuItem 上的方法来修改菜单,而无需等待调用您的委托。

【讨论】:

[NSMenu update] 不调用任何委托方法。我在计时器中动态填充菜单项,并且 NSMenu 在打开时没有更新。 即使您调用 -[NSMenu addItem:]-[NSMenuItem setTitle:] 之类的东西来响应您的计时器,它也不会更新?我确定我看到菜单在打开时会更新,所以这是可能的。 @KenThomases 第一方操作系统时钟可以做到这一点(如果显示秒数会更明显)。

以上是关于如何在打开时更新 NSMenu?的主要内容,如果未能解决你的问题,请参考以下文章

SQL Server 报告服务:如何在打开时停止报告触发

Word 2007:如何在打开时设置“显示推荐样式”

如何在写入期间锁定文件以使其在打开时无法读取?

如何在打开时仅在模式弹出窗口内限制 Tab 键按下?

为啥我的网络应用程序无法在打开时重新加载

在Android工作室中没有错误,应用程序仍然在打开时崩溃