I need to assign a view to an NSMenuItem and do some custom drawing. Basically, I'm adding a little delete button next to the currently selected menu item, among other things. But I want my custom menu item to look and behave like a regular menu item in all other ways. According to the doc:
A menu item with a view does not draw its title, state, font, or other standard drawing attributes, and assigns drawing responsibility entirely to the view.
Ok, so I had to duplicate the look of the state column and the selection gradient, which wasn't that hard. The part I'm having trouble with is the way the menu item "flashes" or "blinks" after it is selected. I'm using an NSTimer to try to mimic this little animation, but it just feels off. How many times does it blink? What time interval should I use? I've experimented a lot and it just feels out of whack.
Has anyone done this before or have other suggestions on how to add a button to a menu item? Maybe there should be a stack exchange site just for custom cocoa drawing...
Here is my code that flashes a custom menu item.
It is actually possible to have your custom view flash like a regular
NSMenuItem
without implementing the animation manually.Note: this uses a private API and also fixes a handful of other strange
NSMenuItem
quirks related to custom views.NSMenuItem.h
Bridging Header
MenuItem.swift
This API really ought to be public, and if you're not developing for the App Store, it might be worth having a look at.
I know this is over a year old, but this was the first hit on my Google search and was unanswered, so I'm posting my answer for sake of those still looking for a solution.
For my app, I used Core Animation with a custom NSView for the NSMenuItem view. I created a new layer-backed view, set the background color, and added it to my custom view. I then animated the layer (the flashing part). Then in the
-(void) animationDidStop:(CAAnimation *)anim finished:(BOOL)flag
callback, I removed the overlay and closed the menu. This doesn't perfectly match the default NSMenu's flash, but I wanted a 37Signals/Stack Overflow Yellow Fade Technique, so it works for me. Here it is in code: