我创建了一个简单的NSStatusBar
,其中NSMenu
设置为菜单。我还在这个菜单中添加了一些NSMenuItems
,它可以正常工作(包括选择器和突出显示),但是一旦我添加自定义视图(setView :),就不会突出显示。
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 SubClass中按照此问题中的代码实现了高亮显示:
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];
}
}
答案 0 :(得分:10)
以上是一个相当不太冗长的版本。它对我有用。 (backgroundColour是一个ivar。)
- (void)drawRect:(NSRect)rect
{
if ([[self enclosingMenuItem] isHighlighted]) {
[[NSColor selectedMenuItemColor] set];
} else if (backgroundColour) {
[backgroundColour set];
}
NSRectFill(rect);
}
答案 1 :(得分:6)
如果要向菜单项添加视图,则该视图必须自己绘制突出显示。你不是免费得到的,我害怕。来自Menu Programming Topics:
带有视图的菜单项不会绘制其标题,状态,字体或其他标准绘图属性,并将绘图责任完全分配给视图。
答案 2 :(得分: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。
答案 3 :(得分:0)
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)
}
}
将其中之一设置为您的menuItem.view
。
(信用属于Sam Soffes,他帮助我弄清了这个问题,并几乎逐字向我发送了该代码。)