如何突出显示特定的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,它会优雅地失败。