我在NSMenuItem中使用一个非常简单的自定义视图(仅包含只读NSTextField和NSSegmentedControl)(使用-setView:
方法)。这部分按预期工作。
问题出现了:在-menuNeedsUpdate:
NSMenu委托方法中,我有条件地隐藏了菜单项。当我拨打[item setHidden:YES]
时,带有自定义视图的菜单项不会隐藏,但其他“香草”菜单项会隐藏。
我的自定义视图是在自己的XIB中构建的,我通过自定义的NSViewController访问它。
更新
即使我选中Interface Builder中的隐藏复选框,菜单项仍然可见,并删除隐藏在代码中的行。
更新2
我还尝试在菜单项上设置hidden
之前和之后在自定义视图上设置hidden
。结果就好像菜单项没有隐藏,但视图是;视图的控件不可见,但它们应该存在差距。
更新3
我修改了Apple的MenuItemView示例代码以隐藏其中一个菜单项(在第87行插入[menuItem setHidden:YES];
),它与我的代码具有相同的效果(也就是说,没有)。
我开始认为隐藏此菜单项的唯一方法是将其视图设置为nil
,当我需要隐藏它并在需要显示它时将其恢复,但它不会似乎应该是必要的。
更新4
使用Mike的答案,下面是我正在使用的代码:
// Declared in the header file
IBOutlet NSMenuItem *previousMenuItem;
IBOutlet NSMenuItem *togglingMenuItem; //Needs to be RETAINED
. . .
- (void)menuNeedsUpdate:(NSMenu *)menu {
BOOL hideItem = YES; // Some criteria, obviously
// Remove the menu item, if it was already present
if ([menu indexOfItem:togglingMenuItem] >= 0) {
[menu removeItem:togglingMenuItem];
}
// Put it back if it should be visible
if (!onePageVisible) {
[menu insertItem:togglingMenuItem
atIndex:[menu indexOfItem:previousMenuItem] + 1];
}
}
答案 0 :(得分:1)
您可以根据需要删除/重新添加项目,而不是隐藏项目吗?
[rootMenu removeItemAtIndex: 23];
答案 1 :(得分:0)
我必须覆盖NSMenuItem的setHidden:方法,并在隐藏时将视图的高度设置为零,如下所示:
- (void) setHidden:(BOOL)flag {
[super setHidden:flag];
NSView *view = [self view];
[view setHidden:flag];
// if our view is hidden, give it a zero height so it won't draw at all
if (flag)
[view setFrameSize:NSMakeSize([view frame].size.width, 0)];
else {
[view setFrameSize:NSMakeSize([view frame].size.width, [self menuItemHeight])];
}
}
答案 2 :(得分:0)
在菜单委托方法菜单中:updateItem:atIndex:shouldCancel:我按标签查找自定义视图菜单项,如果隐藏则将其视图设置为nil,如果可见则指定自定义视图:
- (BOOL)menu:(NSMenu *)menu
updateItem:(NSMenuItem *)item
atIndex:(NSInteger)index
shouldCancel:(BOOL)shouldCancel
{
if ([item tag] == CUSTOM_VIEW_TAG)
{
[item setView:[item isHidden]?nil:customView];
return NO; //we've done our dirty work
}
return YES;
}
答案 3 :(得分:0)
在Swift中,您可以覆盖isHidden
并相应地设置view
:
class PositionHeaderMenuItem: NSMenuItem {
let customView = SomeCustomView()
override var isHidden: Bool {
didSet {
if isHidden {
view = nil
} else {
view = customView
}
}
}
}