NSMenu突出显示特定的NSMenuItem



如何突出显示特定的NSMenuItem ?NSMenu上只有highlightedItem方法,没有setHighlightedItem

UPDATE

通过浏览OS X运行时头,我发现NSMenu上的另一种方法不需要获得碳菜单实现。该方法被称为highlightItem:,其工作方式与人们所期望的一样。

本质上,NSMenu类别可以简化为以下内容:

@interface NSMenu (HighlightItemUsingPrivateAPIs)
- (void)_highlightItem:(NSMenuItem*)menuItem;
@end
@implementation NSMenu (HighlightItemUsingPrivateAPIs)
- (void)_highlightItem:(NSMenuItem*)menuItem
{
    const SEL selHighlightItem = @selector(highlightItem:);
    if ([self respondsToSelector:selHighlightItem]) {
        [self performSelector:selHighlightItem withObject:menuItem];
    }
}
@end

原始回答

虽然似乎没有官方的方法来做到这一点,但可以使用private(!)api。

这是我为NSMenu写的一个类别,它允许你在特定索引中突出显示一个项目:

@interface NSMenu (HighlightItemUsingPrivateAPIs)
- (void)_highlightItemAtIndex:(NSInteger)index;
@end
@implementation NSMenu (HighlightItemUsingPrivateAPIs)
- (void)_highlightItemAtIndex:(NSInteger)index
{
    const SEL selMenuImpl = @selector(_menuImpl);
    if ([self respondsToSelector:selMenuImpl]) {
        id menuImpl = [self performSelector:selMenuImpl];
        const SEL selHighlightItemAtIndex = @selector(highlightItemAtIndex:);
        if (menuImpl &&
            [menuImpl respondsToSelector:selHighlightItemAtIndex]) {
            NSMethodSignature* signature = [[menuImpl class] instanceMethodSignatureForSelector:selHighlightItemAtIndex];
            NSInvocation* invocation = [NSInvocation invocationWithMethodSignature:signature];
            [invocation setTarget:menuImpl];
            [invocation setSelector:selHighlightItemAtIndex];
            [invocation setArgument:&index atIndex:2];
            [invocation invoke];
        }
    }
}
@end

首先获取NSMenu的Carbon菜单实现(NSCarbonMenuImpl),然后使用指定的索引调用highlightItemAtIndex:。这个类别是这样写的,如果苹果决定改变这里使用的私有api,它会优雅地失败。

最新更新