右键单击NSStatusBarButton时调用Action

时间:2015-08-24 17:52:37

标签: macos swift cocoa nsstatusitem nsstatusbar

我正在寻找一种方法来检测何时右键单击NSStatusBarButton(使用Swift)并调用操作。

我目前正在这样设置:

let statusItem = NSStatusBar.systemStatusBar().statusItemWithLength(-1)

func applicationDidFinishLaunching(aNotification: NSNotification) {
    // Insert code here to initialize your application
    if let button = statusItem.button {
        button.image = NSImage(named: "myImage")
        button.alternateImage = NSImage(named: "myImage")
        button.action = Selector("myAction")
    }
}

我想过使用button.rightMouseDown(<#theEvent: NSEvent#>)(因为没有这样的“alternateAction”),但遗憾的是,由于我刚开始编写Mac应用程序,我无法想出一些东西。

  

更新

     

在寻找一种方法时,我看到一些线程告诉子类NSView,但我不知道它应该如何工作(这可能是因为我对编程很新,甚至没有知道如何“子类”)。我仍然认为有一些更简单的方法可以使用它,因为我知道几乎每个statusBar应用程序都会右键单击。

3 个答案:

答案 0 :(得分:3)

你可以子类化和覆盖mouseDown方法,但是从Mac OS X 10.10(Yosemite)开始,有一种更简单的方法:NSGestureRecognizer及其子类:

func applicationDidFinishLaunching(aNotification: NSNotification) {
    // Insert code here to initialize your application
    if let button = statusItem.button {
        button.image = NSImage(named: "myImage")
        button.alternateImage = NSImage(named: "myImage")
        button.action = Selector("myAction")

        // Add right click functionality
        let gesture = NSClickGestureRecognizer()
        gesture.buttonMask = 0x2 // right mouse
        gesture.target = self
        gesture.action = "myRightClickAction:"
        button.addGestureRecognizer(gesture)
    }
}

func myRightClickAction(sender: NSGestureRecognizer) {
    if let button = sender.view as? NSButton {
        // Handle your right click event here
    }
}

答案 1 :(得分:2)

我遇到了与你接受的答案方法相同的问题:它没有为buttonMask 0x2工作,只有buttonMask 0x1。常规NSButton s(但不是NSStatusBarButtons)可以处理NSClickGestureRecognizer,所以也许这就是回答者的想法。我发现建议的另一个解决方案是将NSStatusItem&#39; s view设置为您自己的自定义子类NSView的实例,但从OS X v10.10开始,获取或设置view已被弃用,因此我不想这样做。

我通过添加NSView的自定义子类作为NSStatusItem按钮的子视图解决了这个问题。我的NSView实现-rightMouseUp:以接收正确的鼠标按钮事件,然后将该事件传递给我想要处理鼠标右键单击事件的类给它的块。

这是我的自定义子类:

#import <Cocoa/Cocoa.h>

@interface TTRightClickDetector : NSView

@property (copy) void (^onRightMouseClicked)(NSEvent *);

@end

#import "TTRightClickDetector.h"

实施:

@implementation TTRightClickDetector

- (void)rightMouseUp:(NSEvent *)theEvent
{
    if(self.onRightMouseClicked)
    {
        self.onRightMouseClicked(theEvent);
    }
}

@end

以下是我如何使用它:

self.statusItem = [[NSStatusBar systemStatusBar] statusItemWithLength:NSSquareStatusItemLength];
NSStatusBarButton *button = self.statusItem.button;
button.image = [NSImage imageNamed:@"image"];
button.action = @selector(leftMouseClicked:);

TTRightClickDetector *rightClickDetector = [[TTRightClickDetector alloc] initWithFrame:button.frame];
rightClickDetector.onRightMouseClicked = ^(NSEvent *event){
    [self rightMouseClicked];
};
[button addSubview:rightClickDetector];

答案 2 :(得分:0)

Commanda的答案的快速版本(将NSView子类化并实现mouseDown)。

NSView子类:

class RightMouseHandlerView: NSView {

    var onRightMouseDown: (()->())? = nil

    override func rightMouseDown(with event: NSEvent) {
        super.rightMouseDown(with: event)

        if onRightMouseDown != nil {
            onRightMouseDown!()
        }
    }
}

然后将其添加到状态栏按钮并设置代码块:

statusItem = NSStatusBar.system.statusItem(withLength: NSStatusItem.squareLength)

if let button = statusItem.button {
    let rmhView = RightMouseHandlerView(frame: statusItem.button!.frame)
    rmhView.rightMouseDown = {
        // Do something when right mouse down on button
    }
    button.addSubview(rmView)
}