2015-08-13 62 views

回答

1

UPDATE

通過通過OS X Runtime headers瀏覽我發現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 

原來的答案

雖然似乎沒有被這樣的正式方式,有可能使用私人(!)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的碳菜單實施方案(NSCarbonMenuImpl),然後繼續打電話highlightItemAtIndex:使用指定的索引。如果Apple決定更改此處使用的私有API,則該類別的寫入方式會失敗。