Is it possible for an NSMenu object to notify BEFORE it'll close, not after? Its delegate has method didClose(_:) but I want to update its items before it actually closes, since the disappearing animation is too long and the eye can see the change.
I've tried to monitor NSEvents, but it's useless because NSMenu hasn't public property containing its NSWindow object.
It's theoretically possible to achieve by creating a custom NSViews for each menu items. But I don't like this because then I'll have to draw all the drawing of the items, including selection and click animation.
UPDATE: I've tried to subclass the NSPopUpButton to track menu updates:
class CustomPopUpButton: NSPopUpButton {
var isMenuShown: Bool = false
var onClosingMenu: ((NSMenu)->())?
override var needsDisplay: Bool {
willSet {
if let menu = self.menu, isMenuShown, newValue {
onClosingMenu?(menu)
isMenuShown = false
}
}
}
override func willOpenMenu(_ menu: NSMenu, with event: NSEvent) {
isMenuShown = true
super.willOpenMenu(menu, with: event)
}
}
I'm not proud of that piece of code but it works in general. Yet the 'onClosingMenu' method is being called just after the menu closing animation is finished. Not before.
Video of what I want to achieve: https://drive.google.com/file/d/1GAceKp-fTlurxSybdB3h0epVZrtQjthm/view?usp=sharing
Finally, I've found the solution. No need to fight the system and update something before the button menu closes. I've found the another way and it's pretty simple.
I've subclassed the NSPopUpButton and created another NSMenu in the subclass, called 'attributedMenu'. Overrided all properties of the NSPopUpButton that deal with menu items (insertions and removals) and redirected that actions to the 'attributedMenu' property.
The initial menu property of NSPopUpButton I'm using only for selected items, removing non-selected items right away.
I intercept the click on the button to show 'attributedMenu', not the default menu of the class.
That solution even made possible to display 'multiple values' title if I select more than one element. Like in Apple Pages' font picker when you select text written with multiple fonts. All it takes is to add an NSMenuItem with title 'Multiple Values' and call super to select it.
That's it, now it works as perfect as in Apple Pages font picker button. As long, as I'm not touching the original 'menu' property of NSPopUpButton class.
UPDATE
Uploaded the subclass to GitHub: https://github.com/CineDev/AttributedPopUpButton