Remove highlight from NSMenuItem after click?
I have added a custom view to my subclass of NSMenuItem (which sits in a NSS开发者_高级运维tatusMenu), which means that by default it will not get "highlighted" with a blue/gray background.
I implemented this by using the following code:
- (void)drawRect:(NSRect)rect {
BOOL isHighlighted = [menuItem isHighlighted];
if (isHighlighted) {
[[NSColor selectedMenuItemColor] set];
[NSBezierPath fillRect:rect];
[menuItem addHover];
} else {
[super drawRect:rect];
[menuItem removeHover];
}
}
- (void)mouseUp:(NSEvent*)event {
NSMenuItem *item = [self enclosingMenuItem];
NSMenu *menu = [item menu];
[menu cancelTracking];
[menu performActionForItemAtIndex:[menu indexOfItem:item]];
}
The menu items get highlighted fine, and I can also click on each item; however when I do click on them, they seem to keep the isHighlighted state once I reopen the menu.
Is there a way of changing it so when I click, the highlighted state gets removed when I next open the menu?
Blows my mind that we have to do this instead of a simple NSMenuItem setHighlighted, or NSMenu removeHighlights, or something. Here's a snippet that looks a lot like MrWalker's answer.. It just removes your own menu item from the menu and puts it right back.
NSMenuItem *selfmi = [self enclosingMenuItem];
NSMenu* menu = [[self enclosingMenuItem] menu];
int i = [menu indexOfItem:selfmi];
[menu removeItemAtIndex:i];
[menu insertItem:selfmi atIndex:i];
I fixed this by removing the mouseUp method in my custom view, and then adding another "hidden" NSView inside it which has the following method:
- (BOOL)acceptsFirstResponder {
NSMenu *menu = [item menu];
[menu cancelTracking];
[menu performActionForItemAtIndex:[menu indexOfItem:item]];
return YES;
}
My solution was to remove and re-add the menu items after cancelTracking:
- (void)mouseUp:(NSEvent*)event {
NSMenuItem *item = [self enclosingMenuItem];
NSMenu *menu = [item menu];
if (nil != menu) {
NSInteger index = [menu indexOfItem:item];
[menu cancelTracking];
[menu performActionForItemAtIndex:index];
// hack to reset highlighted menu item state
NSArray *items = [menu itemArray];
[menu removeAllItems];
for (NSMenuItem *item in items) {
[menu addItem:item];
}
}
}
I had a unique situation with the application's main menu, where removing and re-adding the menu items didn't remove the highlight of the menu item. Here's the Swift function I used to remove the highlight by adding a dummy menu item, "clicking" it, then removing the dummy item:
func unhighlightItems(in menu: NSMenu) {
let dummyItem = NSMenuItem(title: "", action: nil, keyEquivalent: "")
menu.addItem(dummyItem)
menu.performActionForItem(at: mainMenu.index(of: dummyItem))
menu.removeItem(dummyItem)
}
精彩评论