【问题标题】:NSMenu highlight specific NSMenuItemNSMenu 突出显示特定的 NSMenuItem
【发布时间】:2015-08-13 13:42:38
【问题描述】:

如何突出显示特定的NSMenuItemNSMenu上只有方法highlightedItem,但没有setHighlightedItem

【问题讨论】:

    标签: macos cocoa nsmenu nsmenuitem


    【解决方案1】:

    更新

    通过浏览OS X Runtime headers,我在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
    

    原始答案

    虽然似乎没有正式的方法来执行此操作,但可以使用私有 (!) 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:。该类别的编写方式是,如果 Apple 决定更改此处使用的私有 API,它会优雅地失败。

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-08-28
    • 1970-01-01
    • 2011-09-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-06
    • 1970-01-01
    相关资源
    最近更新 更多