如何使用自定义视图隐藏菜单项?

发布于 2024-11-04 23:19:27 字数 1598 浏览 1 评论 0原文

我在 NSMenuItem 中使用一个非常简单的自定义视图(仅包含只读 NSTextField 和 NSSegmentedControl)(使用 -setView: 方法)。这部分按预期工作。

问题是:在 -menuNeedsUpdate: NSMenu 委托方法中,我有条件地隐藏了菜单项。当我调用 [item setHidden:YES] 时,具有自定义视图的菜单项不会隐藏,但其他“普通”菜单项会隐藏。

我的自定义视图是在它自己的 XIB 中构建的,我通过自定义 NSViewController 访问它。

更新

即使我在 Interface Builder 中选中“隐藏”复选框,并删除代码中隐藏的行,菜单项仍然可见。

更新 2

我还尝试在菜单项上设置 hidden 之前和之后在自定义视图上设置 hidden 。结果就好像菜单项没有隐藏,但视图是;视图的控件不可见,但它们应该在的位置仍然存在间隙。

更新 3

我修改了 Apple 的 MenuItemView< /a> 添加菜单项后隐藏其中一个菜单项的示例代码(在第 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];
    }
}

I am using a very simple custom view (containing only a read-only NSTextField and an NSSegmentedControl) in an NSMenuItem (using the -setView: method). This part works as expected.

Here's the problem: in the -menuNeedsUpdate: NSMenu delegate method I'm conditionally hiding the menu item. When I call [item setHidden:YES], the menu item with a custom view doesn't hide, but other 'vanilla' menu items do.

My custom view is built in its own XIB, and I'm accessing it through a custom NSViewController.

Update

The menu item stays visible even if I check the Hidden checkbox in Interface Builder, and remove the line where it's hidden in code.

Update 2

I also tried setting hidden on the custom view before and after setting hidden on the menu item. The result is as if the menu item is not hidden, but the view is; the view's controls aren't visible, but there is still a gap where they should be.

Update 3

I modified Apple's MenuItemView sample code to hide one of the menu items after it's added (insert [menuItem setHidden:YES]; at line 87), and it has the same effect as in my code (which is to say, none).

I'm starting to think the only way to hide this menu item will be to set its view to nil when I need to hide it and put it back when I need to show it, but it doesn't seem that should be necessary.

Update 4

Using Mike's answer below, here is the code I'm using:

// 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];
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

拥有 2024-11-11 23:19:27

您可以根据需要删除/重新添加项目,而不是隐藏项目吗?

 [rootMenu removeItemAtIndex: 23];

Rather than hiding an item, can you remove/re-add as needed?

 [rootMenu removeItemAtIndex: 23];
淡笑忘祈一世凡恋 2024-11-11 23:19:27

在菜单委托方法中 menu: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;
}

In menu delegate method menu:updateItem:atIndex:shouldCancel: i find my custom view menu item by tag and set it's view to nil if it is hidden or assign custom view if visible:

- (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;
}
鹤舞 2024-11-11 23:19:27

在 Swift 中,您可以覆盖 isHidden 并相应地设置 view

class PositionHeaderMenuItem: NSMenuItem {
    let customView = SomeCustomView()

    override var isHidden: Bool {
        didSet {
            if isHidden {
                view = nil
            } else {
                view = customView
            }
        }
    }
}

In Swift, you can override isHidden and set view accordingly:

class PositionHeaderMenuItem: NSMenuItem {
    let customView = SomeCustomView()

    override var isHidden: Bool {
        didSet {
            if isHidden {
                view = nil
            } else {
                view = customView
            }
        }
    }
}
与往事干杯 2024-11-11 23:19:27

我必须重写 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])];
}

}

I had to override NSMenuItem's setHidden: method and set the view's height to zero if hidden, like so:

- (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])];
}

}

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文