【问题标题】:How do you hide a Menu Item with a custom view?如何使用自定义视图隐藏菜单项?
【发布时间】:2011-05-03 14:08:34
【问题描述】:

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

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

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

更新

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

更新 2

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

更新 3

我修改了 Apple 的 MenuItemView 示例代码以在添加后隐藏其中一个菜单项(在第 87 行插入 [menuItem setHidden:YES];),它与我的代码中的效果相同(也就是说,没有)。

我开始认为隐藏此菜单项的唯一方法是将其视图设置为nil,当我需要隐藏它并在需要显示它时将其放回原处,但似乎没有这应该是必要的。

更新 4

使用下面迈克的回答,这是我正在使用的代码:

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

【问题讨论】:

    标签: objective-c cocoa macos nsmenuitem nsmenu


    【解决方案1】:

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

     [rootMenu removeItemAtIndex: 23];
    

    【讨论】:

    • 我试图在这个特定的控制器没有对特定菜单项的任何引用的情况下逃脱,但这可能是最好的方法。
    • 我必须承认对以下方面存在深刻的偏见:完成它,交付它,而不是弄清楚它为什么会起作用/不起作用作为读者的练习。祝你好运。
    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

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

      class PositionHeaderMenuItem: NSMenuItem {
          let customView = SomeCustomView()
      
          override var isHidden: Bool {
              didSet {
                  if isHidden {
                      view = nil
                  } else {
                      view = customView
                  }
              }
          }
      }
      

      【讨论】:

        【解决方案4】:

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

        }

        【讨论】:

        • menuItemHeight 在哪里定义?我在 NSMenuItem 的文档中没有看到它。
        • 这是我自己的方法(我认为默认高度是19.0,你可以直接替换)
        猜你喜欢
        • 2015-07-16
        • 2023-03-11
        • 2011-11-18
        • 2014-12-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多