#objective-c #nsmenuitem #nsmenu #nsstatusitem
#objective-c #nsmenuitem #nsmenu #nsstatusitem
Вопрос:
Я добавил пользовательский вид в свой подкласс NSMenuItem (который находится в NSStatusMenu), что означает, что по умолчанию он не будет «выделен» синим / серым фоном.
Я реализовал это с помощью следующего кода:
- (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]];
}
Пункты меню подсвечиваются нормально, и я также могу щелкнуть по каждому пункту; однако, когда я нажимаю на них, они, похоже, сохраняют состояние isHighlighted, как только я снова открываю меню.
Есть ли способ изменить это, чтобы при щелчке выделенное состояние удалялось при следующем открытии меню?
Ответ №1:
Меня поражает, что мы должны сделать это вместо простого NSMenuItem setHighlighted, или NSMenu removeHighlights, или что-то в этомроде. Вот фрагмент, который очень похож на ответ MrWalker.. Это просто удаляет ваш собственный пункт меню из меню и возвращает его обратно.
NSMenuItem *selfmi = [self enclosingMenuItem];
NSMenu* menu = [[self enclosingMenuItem] menu];
int i = [menu indexOfItem:selfmi];
[menu removeItemAtIndex:i];
[menu insertItem:selfmi atIndex:i];
Ответ №2:
Я исправил это, удалив метод mouseUp в моем пользовательском представлении, а затем добавив в него другой «скрытый» NSView, который имеет следующий метод:
- (BOOL)acceptsFirstResponder {
NSMenu *menu = [item menu];
[menu cancelTracking];
[menu performActionForItemAtIndex:[menu indexOfItem:item]];
return YES;
}
Ответ №3:
Мое решение состояло в том, чтобы удалить и повторно добавить пункты меню после отмены отслеживания:
- (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];
}
}
}
Ответ №4:
У меня была уникальная ситуация с главным меню приложения, когда удаление и повторное добавление пунктов меню не приводило к удалению выделения пункта меню. Вот функция Swift, которую я использовал для удаления выделения, добавив фиктивный элемент меню, «щелкнув» по нему, затем удалив фиктивный элемент:
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)
}