使用自定义视图突出显示NSMenuItem?

rdo*_*gan 19 cocoa objective-c nsmenuitem

我创建了一个简单NSStatusBarNSMenu设置作为菜单.我还在NSMenuItems这个菜单中添加了一些,它工作得很好(包括选择器和突出显示),但是一旦我添加自定义视图(setView :),就不会突出显示.

CustomMenuItem *menuItem = [[CustomMenuItem alloc] initWithTitle:@"" action:@selector(openPreferences:) keyEquivalent:@""];
[menuItem foo];
[menuItem setTarget:self];
[statusMenu insertItem:menuItem atIndex:0];
[menuItem release];
Run Code Online (Sandbox Code Playgroud)

我的foo方法是:

- (void)foo {
  NSView *view = [[NSView alloc] initWithFrame:CGRectMake(5, 10, 100, 20)];
  [self setView:view];
}
Run Code Online (Sandbox Code Playgroud)

如果我删除了setView方法,它将突出显示.

我搜索并搜索过,找不到实现/启用此方法的方法.

编辑

我在NSView SubClass中按照此问题中的代码实现了突出显示:

NSMenuItem的视图(NSView子类的实例)在悬停时不突出显示

#define menuItem ([self enclosingMenuItem])

- (void) drawRect: (NSRect) rect {
    BOOL isHighlighted = [menuItem isHighlighted];
    if (isHighlighted) {
        [[NSColor selectedMenuItemColor] set];
        [NSBezierPath fillRect:rect];
    } else {
        [super drawRect: rect];
    }
}
Run Code Online (Sandbox Code Playgroud)

小智 10

这是上面一个相当不太冗长的版本.它对我有用.(backgroundColour是一个伊娃.)

- (void)drawRect:(NSRect)rect
{
    if ([[self enclosingMenuItem] isHighlighted]) {
        [[NSColor selectedMenuItemColor] set];
    } else if (backgroundColour) {
        [backgroundColour set];
    }
    NSRectFill(rect);
}
Run Code Online (Sandbox Code Playgroud)


And*_*rew 8

2019 年更新:

class CustomMenuItemView: NSView {
    private var effectView: NSVisualEffectView

    override init(frame: NSRect) {
        effectView = NSVisualEffectView()
        effectView.state = .active
        effectView.material = .selection
        effectView.isEmphasized = true
        effectView.blendingMode = .behindWindow

        super.init(frame: frame)
        addSubview(effectView)
        effectView.frame = bounds
    }

    required init?(coder decoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    override func draw(_ dirtyRect: NSRect) {
        effectView.isHidden = !(enclosingMenuItem?.isHighlighted ?? false)
    }
}
Run Code Online (Sandbox Code Playgroud)

将其中之一设置为您的menuItem.view.

(功劳属于 Sam Soffes,他帮助我解决了这个问题,并几乎逐字逐句地向我发送了该代码。)


Jos*_*ell 6

如果要向菜单项添加视图,则该视图必须自己绘制突出显示.你不是免费得到的,我害怕.从菜单编程主题:

带有视图的菜单项不会绘制其标题,状态,字体或其他标准图形属性,并将绘图责任完全分配给视图.