2011-05-19 85 views
16

我创建了一个简单的NSStatusBar,其中NSMenu设置为菜单。我也为这个菜单添加了一些NSMenuItems,这些菜单工作正常(包括选择器和高亮显示),但只要添加了自定义视图(setView :),就不会出现高亮显示。使用自定义视图突出显示NSMenuItem?

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

而且我foo的方法是:

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

如果我删除的setView方法,它会突出。

我已搜索和搜索,无法找到实现/启用此方法。

编辑

我按照此问题的代码在我的NSView子类实现亮点:

An NSMenuItem's view (instance of an NSView subclass) isn't highlighting on hover

#define menuItem ([self enclosingMenuItem]) 

- (void) drawRect: (NSRect) rect { 
    BOOL isHighlighted = [menuItem isHighlighted]; 
    if (isHighlighted) { 
     [[NSColor selectedMenuItemColor] set]; 
     [NSBezierPath fillRect:rect]; 
    } else { 
     [super drawRect: rect]; 
    } 
} 
+3

这是一个无用的'#define'。 – NSAddict 2014-02-04 12:21:38

+0

[NSMenuItem的视图(NSView子类的实例)在悬停时不突出显示]的可能重复(http://stackoverflow.com/questions/2917713/an-nsmenuitems-view-instance-of-an-nsview-subclass -isnt-highlighting-on-hove) – nschum 2014-10-25 13:53:16

回答

6

如果要添加一个视图菜单项,该观点必须自己画出亮点。恐怕你不能免费得到这些。从Menu Programming Topics

与视图中的菜单项不画它的标题,状态,字体,或其他标准图纸的属性,并分配完全绘制责任的看法。

+0

啊,该死的 - 谢谢。 – rdougan 2011-05-19 06:04:45

+0

不客气! – 2011-05-19 06:05:24

3

是的,如前所述,您必须自己绘制。我使用AppKit的NSDrawThreePartImage(...)进行绘制,并且还包括使用用户控件外观(蓝色或石墨)的检查。要获取图像,我只是从屏幕截图中截取它们(如果有人知道更好的方法,请添加注释。)这里是我的一块MenuItemView的drawRect的:

// draw the highlight gradient 
if ([[self menuItem] isHighlighted]) { 

    NSInteger tint = [[NSUserDefaults standardUserDefaults] integerForKey:@"AppleAquaColorVariant"]; 
    NSImage *image = (AppleAquaColorGraphite == tint) ? menuItemFillGray : menuItemFillBlue; 

    NSDrawThreePartImage(dirtyRect, nil, image, nil, NO, 
     NSCompositeSourceOver, 1.0, [self isFlipped]); 
} 
else if ([self backgroundColor]) { 

    [[self backgroundColor] set]; 
    NSRectFill(dirtyRect); 
} 

编辑

应该定义这些:

enum AppleAquaColorVariant { 
    AppleAquaColorBlue = 1, 
    AppleAquaColorGraphite = 6, 
}; 

这些对应于在系统偏好设置两个外观选项。此外,menuItemFillGray & menuItemFillBlue只是标准菜单项填充渐变的NSImages。

+0

你能解释一下AppleAquaColorGraphite或menuItemFillGray是什么吗?也许发布整个drawRect方法? ;-) – tamasgal 2011-05-20 23:13:42

+0

我写了一些代码来使用selectedMenuItemColor和渐变绘制突出显示的背景。请参阅[我的答案以完全匹配所选NSMenuItem的背景](http://stackoverflow.com/a/25984748/196844)。 – 2014-09-22 23:57:00

9

这是上面的一个不太冗长的版本。这对我来说很好。 (背景颜色是伊娃。)

- (void)drawRect:(NSRect)rect 
{ 
    if ([[self enclosingMenuItem] isHighlighted]) { 
     [[NSColor selectedMenuItemColor] set]; 
    } else if (backgroundColour) { 
     [backgroundColour set]; 
    } 
    NSRectFill(rect); 
} 
+0

只是好奇:你为什么会用主要API使用美式英语的语言编写英式英语?如果它不是英语,你还会用你的母语吗? – 2014-04-16 06:37:57

+0

请注意,如果drawRect:在您移动鼠标时未被调用,请确保您的菜单项实际上已启用。它需要为存在的选择器设置一个操作。 – robotspacer 2016-09-25 10:32:36