强制更新 Cocoa App 主菜单的 NSMenu(嵌套子菜单) [英] Force NSMenu (nested submenu) update for Main Menu of Cocoa App

查看:14
本文介绍了强制更新 Cocoa App 主菜单的 NSMenu(嵌套子菜单)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

  1. 我插入了一些子菜单作为主菜单的窗口项子菜单
  2. 我有一个从 NSObject 继承的对象实例(假设它的类名是 MenuController),并支持来自 NSMenuDelegate 方法的 2 个:– numberOfItemsInMenu:– menu:updateItem:atIndex:shouldCancel:
  3. 此实例作为蓝色对象添加到 NIB 中以便在运行时唤醒
  4. 步骤 2-3 中的对象配置为子菜单的委托(步骤 1)

现在,我可以在运行时提供子菜单内容.

Now, I can provide submenu content in runtime.

接下来,我执行以下操作:我可以添加新项目或从数组中删除旧项目(在包含菜单标题的 MenuController 中),该数组通过协议和委托映射到实际子菜单.一切正常.除了一件事:我喜欢为我的动态菜单项分配快捷方式.CMD-1、CMD-2、CMD-3 等

Next, I do following: I can add new items or remove old from an array (inside MenuController which contains menu titles) that mapped to real submenu via protocol and delegate. All works just fine. Except one thing: I like assign shortcuts to my dynamic menu items. CMD-1, CMD-2, CMD-3, etc

Window/MySubmenu/MyItem1 CMD-1, MyItem2 CMD-2, ...

Window / MySubmenu / MyItem1 CMD-1, MyItem2 CMD-2, ...

因此,对于调用某些项目,我不想转到 Window/MySubmenu/MyItem 以通过鼠标单击它,我只想按一个快捷方式,例如 CMD-3 来调用该项目.

So, for call some items I don't wanna go to Window / MySubmenu / MyItem to click it by mouse, I wanna press just one shortcut, like CMD-3 to call the item.

好的,它定期按预期工作.但是,一般来说,除了打开 Window/MySubmenu 以重新加载其内容之外,我无法将嵌套子菜单的更改通知主菜单.重现该问题的一种稳定方法 - 只需尝试删除某些项目并按下为其分配的旧快捷方式,在您创建新项目作为已删除项目的替换后 - 宾果游戏 - 在导航到 Window/MySubmenu 以查看当前子菜单内容之前,快捷方式将不起作用.

Ok, periodically it works as expected. But, generally, I have no way to inform Main Menu about my nested submenu changes, except open the Window / MySubmenu to reload its content. One stable way to reproduce the issue - just try to remove some item and press its old shortcut assigned to it, after you create new item as replace for deleted - bingo - shortcut wont work before you navigate to Window / MySubmenu to see current submenu content.

我不知道强制主菜单重建其子菜单的方法...我试过:[[NSApp mainMenu] 更新] 和游戏与 NSNotificationCenter 发送 NSMenuDidAddItemNotification、NSMenuDidRemoveItemNotification、NSMenuDidChangeItemNotification

I don't know a way to force main menu to rebuild its submenus... I tried: [[NSApp mainMenu] update] and games with NSNotificationCenter for send NSMenuDidAddItemNotification, NSMenuDidRemoveItemNotification, NSMenuDidChangeItemNotification

我尝试了我的子菜单的出口并显式调用更新方法 - 没有办法......有时 AppKit 调用我的委托方法 - 我看到了,有时它不想调用任何东西.看起来像是随机策略.

I tried outlet to my submenu and call to update method explicitly - there is no way... Some times AppKit calls my delegate methods - and I see that, sometimes it doesn't want to call anything. Looks like a random strategy.

如何确保在some call"之后我的子菜单在内部数组修改后处于实际状态?

How can I make sure that after "some call" my submenu will be in actual state after internal array modifications?

推荐答案

要实现 1:1 映射,请在委托中实现这 3 个方法:

To implement 1:1 mapping, implement in delegate these 3 methods:

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

- (NSInteger)numberOfItemsInMenu:(NSMenu *)menu

- (void)menuNeedsUpdate:(NSMenu *)menu
{
    if (!attachedMenu)
        attachedMenu = menu;
    if (!menu)
        menu = attachedMenu;
    NSInteger count = [self numberOfItemsInMenu:menu];
    while ([menu numberOfItems] < count)
        [menu insertItem:[[NSMenuItem new] autorelease] atIndex:0];
    while ([menu numberOfItems] > count)
        [menu removeItemAtIndex:0];
    for (NSInteger index = 0; index < count; index++)
        [self menu:menu updateItem:[menu itemAtIndex:index] atIndex:index shouldCancel:NO];
}

attachedMenu - 是 NSMenu* 类型的内部变量

attachedMenu - is internal var of type NSMenu*

接下来,当您想强制刷新子菜单时,随时 - 只需调用

Next, when you wanna force refresh the submenu, anytime - just call

[self menuNeedsUpdate:nil];

这篇关于强制更新 Cocoa App 主菜单的 NSMenu(嵌套子菜单)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆