2013-12-21 3 views
2

This answer описывает, как установить шрифт и, следовательно, цвет шрифта NSMenuItem.Установите цвет шрифта NSMenuItem, если он выделен

Чтобы предупредить пользователя о проблеме с выбранным элементом во всплывающем меню, я установил цвет в красный цвет. Отлично работает, за исключением случаев, когда элемент выделен, фон становится синим, а мой красный-на-синем трудно читать и выглядит паршиво. Шрифт регулярных пунктов меню изменяется с черного на белый. Я хотел бы, чтобы мой измененный пункт меню менял цвет шрифта, когда он был выделен таким образом.

Это динамическое меню. Я устанавливаю шрифт/цвет при создании элементов в -menuNeedsUpdate. Конечно, [NSMenuItem isHighlighted] возвращает NO там, потому что элемент только что был создан.

Я также попытался добавить наблюдателя на NSMenuDidBeginTrackingNotification и NSMenuDidBeginTrackingNotification, но это не помогает, потому что эти два уведомления всегда получали в парах, 5:57 пара каждый раз, когда я нажимаю на меню, а затем, после отслеживания закончился приходит еще один -menuNeedsUpdate: он снова создает все с нуля. Я не уверен, что это означает, когда меню «отслеживание», но, видимо, это не то, что я хочу.

Я думал, что спросить, если кто-нибудь когда-нибудь придумать хороший ответ на это, прежде чем я пойти и сделать что-то действительно kludgey как these guys did for a similar NSMenuItem quandary.

ответ

3

Вы можете реализовать меню delegate, чтобы получать уведомление, когда элемент подсвечен.

#pragma mark - NSMenuDelegate 

- (void)menu:(NSMenu *)menu willHighlightItem:(NSMenuItem *)item { 
    [menu.highlightedItem nik_restoreTextColor]; 
    [item nik_overrideTextColor:[NSColor selectedMenuItemTextColor]]; 
} 

Должно быть довольно простым удаление и повторное добавление цвета одного предмета. Но вот общее решение, которое я использую, чтобы запомнить, а затем восстановить цвет:

@implementation NSMutableAttributedString(NIKExchangeAttribute) 

- (void)nik_renameAttribute:(NSString *)originalAttribute to:(NSString *)newAttribute { 
    NSRange fullRange = NSMakeRange(0, self.length); 
    [self removeAttribute:newAttribute range:fullRange]; 
    [self enumerateAttribute:originalAttribute 
        inRange:fullRange 
        options:0 
        usingBlock:^(id value, NSRange range, BOOL *stop) { 
     [self addAttribute:newAttribute value:value range:range]; 
    }]; 
    [self removeAttribute:originalAttribute range:fullRange]; 
} 

@end 

static NSString *const ORIGINAL_COLOR_KEY = @"nik_originalColor"; 

@implementation NSMenuItem(NIKOverrideColor) 

- (void)nik_overrideTextColor:(NSColor *)textColor { 
    NSMutableAttributedString *title = [self.attributedTitle mutableCopy]; 
    [title nik_renameAttribute:NSForegroundColorAttributeName to:ORIGINAL_COLOR_KEY]; 
    [title addAttribute:NSForegroundColorAttributeName 
        value:textColor 
        range:NSMakeRange(0, title.length)]; 
    self.attributedTitle = title; 
} 

- (void)nik_restoreTextColor { 
    NSMutableAttributedString *title = [self.attributedTitle mutableCopy]; 
    [title nik_renameAttribute:ORIGINAL_COLOR_KEY to:NSForegroundColorAttributeName]; 
    self.attributedTitle = title; 
} 

@end 
Смежные вопросы