I am attempting to add a custom view to an NSMenuItem in the OS X 10.10 Yosemite menu bar.
The custom view is simply an NSView background with an NSTextField “label”.
The problem is that the background NSView is given Yosemite-style vibrancy/transparency when added to the menu. The NSTextfield label is not.
Through the use of NSRectFillUsingOperation
I've gotten this to look good for some background colors in Yosemite. But others continue to not match. When it is working, after manually "highlighting" the view, the original colors change and no longer match. I can dig up some example code for this if needed.
Then, when it is looking somewhat good in Yosemite, it looks terrible in 10.9 Mavericks.
I've also tried setting the wantsLayer
property to YES to turn the view into a CALayer-backed view. This creates other issues such as text not anti-aliasing correctly against a clear background.
My Question:
How do I display a label on top of a NSMenuItem custom view? The label's background must exactly match the view's background. Solution must work in Yosemite and Mavericks.
Example code below:
self.statusItem = [[NSStatusBar systemStatusBar] statusItemWithLength:NSVariableStatusItemLength]; [self.statusItem setTitle:@"TEST"]; [self.statusItem setHighlightMode:YES]; [self.statusItem setEnabled:YES]; [self.statusItem setTarget:self]; NSMenu *menu = [[NSMenu alloc] init]; [menu addItemWithTitle:@"Disabled menu item" action:nil keyEquivalent:@""]; [menu addItemWithTitle:@"Enabled menu item" action:@selector(enabled) keyEquivalent:@""]; NSTextField *label = [[NSTextField alloc] initWithFrame:NSMakeRect(30, 20, 50, 20)]; label.stringValue = @"label"; label.editable = NO; label.bordered = NO; label.backgroundColor = [NSColor blueColor]; //label.backgroundColor = [NSColor clearColor]; PKMenuItemView *view = [[PKMenuItemView alloc] initWithFrame:NSMakeRect(0, 0, 200, 50)]; [view addSubview:label]; NSMenuItem *viewMenuItem = [[NSMenuItem alloc] init]; [viewMenuItem setView:view]; [menu addItem:viewMenuItem]; self.statusItem.menu = menu;
I've subclassed the NSView to override drawRect:
and draw a colored background:
- (void)drawRect:(NSRect)dirtyRect { [super drawRect:dirtyRect]; [[NSColor blueColor] setFill]; NSRectFill(dirtyRect); //NSRectFillUsingOperation(dirtyRect, NSCompositeSourceOver); }
It is surely kinda hack, but it worked for me. Try adding an NSImageView with empty image to your custom view. Image view must be occupy the whole view.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With