在突出显示时将NSMenuItem的字体颜色设置为交替

时间:2013-12-21 18:53:42

标签: macos cocoa fonts nsmenuitem

This answer描述了如何设置NSMenuItem的字体,以及字体颜色。

为了提醒用户弹出菜单中所选项目的问题,我将颜色设置为红色。效果很好,除非项目突出显示,背景变为蓝色,我的红蓝色很难阅读,看起来很糟糕。常规菜单项的字体从黑色变为白色。我希望修改后的菜单项在突出显示时更改其字体颜色。

这是一个动态菜单。我在-menuNeedsUpdate中设置创建项目时的字体/颜色。当然, - [NSMenuItem isHighlighted]在那里返回NO,因为刚刚创建了该项目。

我还尝试在NSMenuDidBeginTrackingNotification和NSMenuDidBeginTrackingNotification上添加观察者,但这也无济于事,因为这两个通知总是成对接收,每次单击菜单时都会有三到六对,然后跟踪后有结束来了另一个-menuNeedsUpdate:它再次从头开始重新创建所有内容。当菜单“跟踪”时,我不确定这意味着什么,但显然这不是我想要的。

我想我会问是否有人为此做过一个很好的答案,然后再去做一些像<{3}}这样真正 kludgey的事情。

1 个答案:

答案 0 :(得分: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