开发者

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)
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜