NSMenu 突出显示特定的 NSMenuItem

Pet*_*isu 5 macos cocoa nsmenu nsmenuitem

如何突出一个特定的NSMenuItem?现在只是在方法highlightedItemNSMenu,但没有setHighlightedItem

lem*_*ojo 2

更新

通过浏览OS X 运行时标头,我发现了另一种NSMenu不需要获取 Carbon 菜单实现的方法。该方法被调用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
Run Code Online (Sandbox Code Playgroud)

原答案

虽然似乎没有官方的方法可以做到这一点,但可以使用私有(!)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
Run Code Online (Sandbox Code Playgroud)

首先,它获取 的 Carbon 菜单实现 ( NSCarbonMenuImpl) NSMenu,然后继续highlightItemAtIndex:使用指定的索引进行调用。该类别的编写方式是,如果 Apple 决定更改此处使用的私有 API,该类别会正常失败。