這是我想出了一個解決方案。它工作得很好,但有一件事我不滿意:在右鍵菜單中選擇一個選項後,狀態項保持高亮顯示。只要你與別的東西互動,突出點就會消失。
另請注意,popUpStatusItemMenu:
自OS X 10.10(優勝美地)起「軟性棄用」,並將在未來版本中正式棄用。目前,它的工作原理並不會給你任何警告。希望我們在得到正式棄用之前有一個完全支持的方式來做到這一點 - 如果您同意,我建議您使用filing a bug report。
首先,您需要一些屬性和枚舉:
typedef NS_ENUM(NSUInteger,JUNStatusItemActionType) {
JUNStatusItemActionNone,
JUNStatusItemActionPrimary,
JUNStatusItemActionSecondary
};
@property (nonatomic, strong) NSStatusItem *statusItem;
@property (nonatomic, strong) NSMenu *statusItemMenu;
@property (nonatomic) JUNStatusItemActionType statusItemAction;
然後在某個時候,你會想設置的狀態項:
NSStatusItem *item = [[NSStatusBar systemStatusBar] statusItemWithLength:29.0];
NSStatusBarButton *button = item.button;
button.image = [NSImage imageNamed:@"Menu-Icon"];
button.target = self;
button.action = @selector(handleStatusItemAction:);
[button sendActionOn:(NSLeftMouseDownMask|NSRightMouseDownMask|NSLeftMouseUpMask|NSRightMouseUpMask)];
self.statusItem = item;
然後你只需要處理由狀態項按鈕發送的動作:
- (void)handleStatusItemAction:(id)sender {
const NSUInteger buttonMask = [NSEvent pressedMouseButtons];
BOOL primaryDown = ((buttonMask & (1 << 0)) != 0);
BOOL secondaryDown = ((buttonMask & (1 << 1)) != 0);
// Treat a control-click as a secondary click
if (primaryDown && ([NSEvent modifierFlags] & NSControlKeyMask)) {
primaryDown = NO;
secondaryDown = YES;
}
if (primaryDown) {
self.statusItemAction = JUNStatusItemActionPrimary;
} else if (secondaryDown) {
self.statusItemAction = JUNStatusItemActionSecondary;
if (self.statusItemMenu == nil) {
NSMenu *menu = [[NSMenu alloc] initWithTitle:@""];
[menu addItemWithTitle:NSLocalizedString(@"Quit",nil) action:@selector(terminate:) keyEquivalent:@""];
self.statusItemMenu = menu;
}
[self.statusItem popUpStatusItemMenu:self.statusItemMenu];
} else {
self.statusItemAction = JUNStatusItemActionNone;
if (self.statusItemAction == JUNStatusItemActionPrimary) {
// TODO: add whatever you like for the primary action here
}
}
}
所以基本上,handleStatusItemAction:
被調用鼠標放下並鼠標移動鼠標按鈕。當一個按鈕關閉時,它會跟蹤它是否應該執行主要操作或次要操作。如果是次要操作,則立即處理,因爲菜單通常出現在鼠標下方。如果這是主要操作,則在鼠標上處理。
幾個筆記(以下片段在Swift中): a)通過爲StatusItem對象設置'item.highlightMode = false',可以解決右鍵單擊後剩下的高亮部分。 b)主動作的情況應該首先在最後的else塊(在'self.statusItemAction = JUNStatusItemActionNone;'之前)以使所需的行爲起作用。否則,您正在設置'self.statusItemAction'的值,然後立即檢查它是否有所不同。 – AmusedToDeath