Cocoa应用程序主菜单的强制NSMenu(嵌套子菜单)更新 我有一些子菜单作为主菜单的窗口项子菜单插入 我有一个从NSObject继承的对象实例(假设其类名为MenuController),并支持从NSMenuDelegate方法继承的2: –NumberOfItems菜单: –菜单:更新项:索引:应取消: 此实例作为蓝色对象添加到NIB中,以便在运行时唤醒 步骤2-3中的对象配置为子菜单的委托(步骤1)
现在,我可以在运行时提供子菜单内容 接下来,我将执行以下操作:我可以添加新项或从数组中删除旧项(在包含菜单标题的MenuController中),该数组通过协议和委托映射到真实子菜单。 一切正常。 除了一件事:我喜欢为我的动态菜单项指定快捷方式。 CMD-1、CMD-2、CMD-3等 Window/MySubmenu/MyItem1 CMD-1、MyItem2 CMD-2 所以,对于调用一些我不想去Window/MySubmenu/MyItem用鼠标点击的项目,我只想按一个快捷键,比如CMD-3来调用该项目 好的,它会按预期周期工作。但是,一般来说,除了打开Window/MySubmenu以重新加载其内容外,我无法将嵌套子菜单的更改通知主菜单。 重现问题的一种稳定方法是,在创建新项目作为“替换已删除项目”后,尝试删除某些项目并按指定给它的旧快捷方式-宾果-在导航到“窗口/我的子菜单”以查看当前子菜单内容之前,快捷方式不起作用 我不知道如何强制主菜单重建其子菜单。。。 我尝试了:[[NSApp Main Menu]update]和使用NSNotificationCenter的游戏,用于发送NSMenudAdItemNotification、NSMenudRemoveItemNotification、NSMenudChangeItemNotification 我试图打开我的子菜单并显式调用update方法-没有办法。。。 有时候AppKit调用我的委托方法——我看到,有时候它不想调用任何东西。看起来像是一个随机策略 如何确保在“某些调用”后,我的子菜单在内部阵列修改后处于实际状态 我试过:[[NSApp主菜单]更新] 你在正确的轨道上。在这种情况下,Cocoa应用程序中的并行阵列可能是有保证的Cocoa应用程序主菜单的强制NSMenu(嵌套子菜单)更新 我有一些子菜单作为主菜单的窗口项子菜单插入 我有一个从NSObject继承的对象实例(假设其类名为MenuController),并支持从NSMenuDelegate方法继承的2: –NumberOfItems菜单: –菜单:更新项:索引:应取消: 此实例作为蓝色对象添加到NIB中,以便在运行时唤醒 步骤2-3中的对象配置为子菜单的委托(步骤1),cocoa,appkit,nsmenu,Cocoa,Appkit,Nsmenu,现在,我可以在运行时提供子菜单内容 接下来,我将执行以下操作:我可以添加新项或从数组中删除旧项(在包含菜单标题的MenuController中),该数组通过协议和委托映射到真实子菜单。 一切正常。 除了一件事:我喜欢为我的动态菜单项指定快捷方式。 CMD-1、CMD-2、CMD-3等 Window/MySubmenu/MyItem1 CMD-1、MyItem2 CMD-2 所以,对于调用一些我不想去Window/MySubmenu/MyItem用鼠标点击的项目,我只想按一个快捷键,比如CMD-3
nil
,因为NSArray只能包含对象,nil
表示没有对象。)菜单:updateItem:atIndex:shouldCancel:
时,在返回新菜单项之前使用新菜单项您可能想寻求更好的方法。要实现1:1映射,请在委派中实现以下3种方法:
- (BOOL)menu:(NSMenu *)menu
updateItem:(NSMenuItem *)item
atIndex:(NSInteger)index shouldCancel:(BOOL)shouldCancel
及
及
在代表调用
numberofitems菜单中:
callremoveAllItems
。。。这很奇怪,但除此之外,菜单不会更新,即使它需要一个代表
- (NSInteger)numberOfItemsInMenu:(NSMenu*)menu {
[menu removeAllItems];
return [self.templateURLs count] + 2;
}
谢谢彼得。然而,我寻找方法将数组1:1映射到菜单(而不是反向)。我找到了解决方案——就像您所说的。为了防止内存消耗的死环(如果第一次没有使用nil调用初始化菜单),在menuedsupdate中需要一个附加条件:if(!menu)return;/*计数前=*/
- (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];
}
[self menuNeedsUpdate:nil];
- (NSInteger)numberOfItemsInMenu:(NSMenu*)menu {
[menu removeAllItems];
return [self.templateURLs count] + 2;
}