首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Cocoa应用程序主菜单强制NSMenu (嵌套子菜单)更新

Cocoa应用程序主菜单强制NSMenu (嵌套子菜单)更新
EN

Stack Overflow用户
提问于 2010-02-09 21:00:11
回答 3查看 5.4K关注 0票数 2
  1. 我有一些子菜单插入为主菜单的窗口项子菜单。
  2. 我有一个对象的实例(假设它的类名是MenuController)从NSObject继承而来,并支持来自NSMenuDelegate方法的2:- numberOfItemsInMenu:- menu:updateItem:atIndex:shouldCancel:
  3. 此实例作为Blue添加到NIB中,以便在运行时唤醒。
  4. 步骤2-3中配置为子菜单委托的对象(步骤1)

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

接下来,我可以添加新项或从一个数组(包含菜单标题的MenuController中)删除旧的项,该数组通过协议和委托映射到真正的子菜单。一切都很好。除了一件事:我喜欢为我的动态菜单项分配快捷方式。CMD-1,CMD-2,CMD-3等

窗口/ MySubmenu / MyItem1 CMD-1,MyItem2 CMD-2,

因此,对于调用某些项目,我不想转到窗口/ MySubmenu / MyItem通过鼠标单击它,我只想按一个快捷方式,像CMD-3来调用项目。

好的,它按预期周期性地工作。但是,通常,除了打开窗口/ MySubmenu以重新加载其内容外,我无法将嵌套的子菜单更改通知主菜单。一个稳定的方法来重现这个问题-只要尝试删除一些项目,并按它分配给它的旧快捷方式,在您创建新项目作为已删除的替换后--宾果--在您导航到窗口/ MySubmenu查看当前的子菜单内容之前,快捷键无法工作。

我不知道如何迫使主菜单重建子菜单.我试过:[NSApp mainMenu更新]和NSNotificationCenter玩NSMenuDidAddItemNotification,NSMenuDidRemoveItemNotification,NSMenuDidChangeItemNotification游戏。

我试着打开子菜单并显式调用update方法--没有办法.有时,AppKit调用我的委托方法--我看到了,有时它不想调用任何东西。看起来是个随机策略。

如何确保在“一些调用”之后,经过内部数组修改后,我的子菜单将处于实际状态?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2010-02-10 12:30:37

要实现1:1映射,在委托中实现以下3种方法:

代码语言:javascript
复制
- (BOOL)menu:(NSMenu *)menu
updateItem:(NSMenuItem *)item 
atIndex:(NSInteger)index shouldCancel:(BOOL)shouldCancel

代码语言:javascript
复制
- (NSInteger)numberOfItemsInMenu:(NSMenu *)menu

代码语言:javascript
复制
- (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*型的内部变量

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

代码语言:javascript
复制
[self menuNeedsUpdate:nil];
票数 5
EN

Stack Overflow用户

发布于 2010-02-10 09:11:25

我试过:[NSApp mainMenu更新]…

你走在正确的轨道上。这可能是在Cocoa应用程序中需要并行数组的一种情况。

  1. 保持一个可更改的菜单项数组,与菜单项所代表的模型对象数组并行。
  2. 当您接收到numberOfItemsInMenu:时,将您拥有的模型对象的数量与菜单项数组的计数进行比较。如果它较少,请使用方法缩短菜单项数组。如果是更多的话,就用NSNull对象填充数组。(这里不能使用nil,因为NSArray只能包含对象,而nil是对象的缺失。)
  3. 当您收到menu:updateItem:atIndex:shouldCancel:时,在返回新菜单项之前,使用新菜单项的替换该索引处数组中的对象。
  4. 遵循NSMenuValidation协议,如方法中所提到的。在您的验证方法中,在数组中查找菜单项的索引。,然后在模型对象数组中的索引处获取模型对象,并从它更新菜单项。如果您在雪豹上,您可以发送菜单项的菜单消息,以确定您需要从模型对象中授予哪些属性值。

警告是,该对象,即菜单的委托,也必须是菜单项的目标。我猜是的。如果不是,这将在第4步失败,因为验证消息被发送到菜单项的目标。

您可能想要提交增强请求请求一个更好的方法。

票数 3
EN

Stack Overflow用户

发布于 2016-05-18 21:53:56

在委托调用numberOfItemsInMenu:调用removeAllItems..。这很奇怪,但否则菜单就不会更新,甚至还会调用委托

代码语言:javascript
复制
- (NSInteger)numberOfItemsInMenu:(NSMenu*)menu {

    [menu removeAllItems];

    return [self.templateURLs count] + 2;

}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2232476

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档