Objective c 如何隐藏具有自定义视图的菜单项?
我在NSMenuItem中使用了一个非常简单的自定义视图(仅包含一个只读NSTextField和一个NSSegmentedControl)(使用Objective c 如何隐藏具有自定义视图的菜单项?,objective-c,cocoa,macos,nsmenuitem,nsmenu,Objective C,Cocoa,Macos,Nsmenuitem,Nsmenu,我在NSMenuItem中使用了一个非常简单的自定义视图(仅包含一个只读NSTextField和一个NSSegmentedControl)(使用-setView:方法)。这部分按预期工作 问题是:在-menuedsupdate:NSMenu委托方法中,我有条件地隐藏菜单项。当我调用[item setHidden:YES]时,具有自定义视图的菜单项不会隐藏,但其他“普通”菜单项会隐藏 我的自定义视图是在自己的XIB中构建的,我通过自定义NSViewController访问它 更新 即使我选中Int
-setView:
方法)。这部分按预期工作
问题是:在-menuedsupdate:
NSMenu委托方法中,我有条件地隐藏菜单项。当我调用[item setHidden:YES]
时,具有自定义视图的菜单项不会隐藏,但其他“普通”菜单项会隐藏
我的自定义视图是在自己的XIB中构建的,我通过自定义NSViewController访问它
更新
即使我选中Interface Builder中的“隐藏”复选框并删除代码中隐藏的行,菜单项仍保持可见
更新2
在菜单项上设置hidden
之前和之后,我还尝试在自定义视图上设置hidden
。结果就好像菜单项没有隐藏,但视图是隐藏的;视图的控件不可见,但它们应该位于的位置仍有一个间隙
更新3
我修改了苹果的示例代码,在添加菜单项后隐藏其中一个菜单项(在第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];
}
}
您是否可以根据需要删除/重新添加项目,而不是隐藏项目
[rootMenu removeItemAtIndex: 23];
我必须重写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])];
}
}在菜单中“委托方法”菜单:更新项:索引:应取消:我按标记查找自定义视图菜单项,并将其视图设置为零(如果隐藏),或指定自定义视图(如果可见):
- (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;
}
在Swift中,您可以覆盖
ishiden
,并相应地设置视图
:
class PositionHeaderMenuItem: NSMenuItem {
let customView = SomeCustomView()
override var isHidden: Bool {
didSet {
if isHidden {
view = nil
} else {
view = customView
}
}
}
}
我试图在这个特定控制器没有任何特定菜单项的引用的情况下离开,但这可能是最好的方法。我必须承认,我对以下方面有着深刻的偏见:完成它,发货,让读者了解它到底为什么起作用/不起作用。祝你好运。
menuItemHeight
在哪里定义?我在NSMenuItem的文档中没有看到它。这是我自己的方法(我认为默认高度是19.0,你可以替换它)