【问题标题】:Call Action when NSStatusBarButton is right-clicked右键单击 NSStatusBarButton 时调用 Action
【发布时间】:2015-08-24 17:52:37
【问题描述】:

我正在寻找一种方法来检测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 应用程序都可以右键单击。

【问题讨论】:

标签: macos swift cocoa nsstatusitem nsstatusbar


【解决方案1】:

您可以子类化和覆盖 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
    }
}

【讨论】:

  • 首先感谢您的回答。不幸的是,我遇到了一个非常奇怪的问题。使用buttonMask = 0x2 它根本没有检测到右键单击,但是将掩码更改为0x1 以某种方式检测到正常的左键单击。这对我来说似乎很奇怪,因为我根本没有改变任何其他东西。
【解决方案2】:

对于接受的答案方法,我遇到了与您相同的问题:它不适用于 buttonMask 0x2,仅适用于 buttonMask 0x1。普通的NSButtons(但不是NSStatusBarButtons)可以处理NSClickGestureRecognizers,所以也许这就是回答者的想法。我发现建议的另一个解决方案是将NSStatusItemview 设置为您自己的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];

【讨论】:

    【解决方案3】:

    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)
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-10-05
      • 1970-01-01
      • 2022-01-19
      • 1970-01-01
      • 2012-11-06
      • 1970-01-01
      • 2011-01-11
      相关资源
      最近更新 更多