将按钮操作重定向到Swift

时间:2016-06-30 01:55:50

标签: swift nsstatusitem nsstatusbar

这可能是一个简单的问题,但我是Swift的新手,并且不知道谷歌的哪些条款。

对于菜单栏应用程序,我实现了一个名为doSomething的自定义函数,当它绑定到某个按钮时可以正常工作:

Class MainViewController:
{
    @IBAction func doSomething(sender: NSButton) 
    {
        // Do something when NSButton is pressed
    }
}

但是,我需要区分左键和右键单击按钮,在我的例子中是NSStatusBarButton。根据{{​​3}}的建议,我已将以下内容写入AppDelegate.swift

@NSApplicationMain class AppDelegate: NSObject, NSApplicationDelegate {

    let statusItem = NSStatusBar.systemStatusBar().statusItemWithLength(-2)
    var mainViewController: MainViewController?


    func applicationDidFinishLaunching(notification: NSNotification) 
    {
        if let button = statusItem.button 
        {
            button.action = #selector(customClickAction)
            button.sendActionOn(Int(NSEventMask.RightMouseDownMask.rawValue | NSEventMask.LeftMouseDownMask.rawValue))
        }
    }


    func customClickAction(sender: NSButton) 
    {
        let event:NSEvent! = NSApp.currentEvent!

        if (event.type == NSEventType.RightMouseDown) 
        {
            print("Right mouse button down")
        } 
        else if (event.type == NSEventType.LeftMouseDown)
        {
            print("Left mouse button down")
            mainViewController?.doSomething(_:) // THIS DOES NOT WORK
         }
    }
}

上面的代码片段为我提供了XCode中的错误消息“表达式解析为未使用的函数”。我无法弄清楚如何从doSomething函数中的MainViewController类正确调用函数customClickAction,或者等效地,如何通过{{重定向statusItem.button的操作1}}到customClickAction。如果这个问题对于Swift专家来说似乎过于微不足道,我很抱歉,但我真的在绝望中试图弄清楚这一点。

编辑:

如果函数doSomething不存在,我只需在customClickAction中编写button.action = #selector(mainViewController?.show(_:))来调用该函数,一切正常。但是,我的部分问题是,在我的自定义函数中执行相同操作会在第一次按下鼠标左键时覆盖绑定。

1 个答案:

答案 0 :(得分:2)

Here是来自具有相同Expression resolves to an unused function问题的人的问题。在他/她的情况下,问题是函数在函数后没有()被调用,所以stop而不是stop()(如果这是有道理的)。

好的,现在我们知道编译器试图告诉我们的内容,我们可以尝试找出解决问题的方法。

在您的情况下,问题是您需要向sender方法发送doSomething参数,并且该参数的类型必须为NSButton,因为您已声明自己。

@IBAction func doSomething(sender: NSButton) 
{
    // Do something when NSButton is pressed
}

因此,在您的情况下,如果您只是将sender作为参数传递给customClickAction,请执行以下操作:

func customClickAction(sender: NSButton)
{
    let event:NSEvent! = NSApp.currentEvent!

    if (event.type == NSEventType.RightMouseDown)
    {
        print("Right mouse button down")
    }
    else if (event.type == NSEventType.LeftMouseDown)
    {
        print("Left mouse button down")
        mainViewController?.doSomething(sender)
    }
}

然后编译器似乎很高兴。

以下是整个AppDelegate

@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {

    let statusItem = NSStatusBar.systemStatusBar().statusItemWithLength(-2)
    var mainViewController: MainViewController? = MainViewController() //initialized


    func applicationDidFinishLaunching(notification: NSNotification)
    {
        if let button = statusItem.button
        {
            button.action = #selector(customClickAction)
            button.sendActionOn(Int(NSEventMask.RightMouseDownMask.rawValue | NSEventMask.LeftMouseDownMask.rawValue))
        }
    }


    func customClickAction(sender: NSButton)
    {
        let event:NSEvent! = NSApp.currentEvent!

        if (event.type == NSEventType.RightMouseDown)
        {
            print("Right mouse button down")
        }
        else if (event.type == NSEventType.LeftMouseDown)
        {
            print("Left mouse button down")
            mainViewController?.doSomething(sender)
        }
    }
}

希望对你有所帮助。

跟进您的修改

你写

  

如果函数customClickAction不存在,我只需在applicationDidFinishLaunching中编写button.action = #selector(mainViewController?.show(_ :))来调用该函数,一切正常。

我可能误解了这里的一切,但为什么你不“只”将doSomething方法分配给button.action,然后将左或右按钮的检查移动到方法

所以你要说:

button.action = #selector(mainViewController?.doSomething(_:))

,您的doSomething将如下所示:

    @IBAction func doSomething(sender: NSButton)
{
    // Do something when NSButton is pressed
    let event:NSEvent! = NSApp.currentEvent!

    if (event.type == NSEventType.RightMouseDown)
    {
        print("Right mouse button down")
    }
    else if (event.type == NSEventType.LeftMouseDown)
    {
        print("Left mouse button down")
    }
}

如果我这样做的话,“鼠标左键按下”和“鼠标右键按下”会显示在我的控制台中。

Swift 3更新

正如@ixany在评论中写道:

  

是我还是Swift 3? :)似乎你的解决方案需要更新到Swift 3,因为我无法使用当前的Xcode Beta进行调整

我尝试将语法升级到Swift 3.0,但似乎存在一些问题。

第一个问题是,在分配doSomething时,我无法直接转到MainViewController selector方法,所以我添加了一个“本地”步骤。

AppDelegate现在看起来像这样:

import Cocoa

@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {

    @IBOutlet weak var window: NSWindow!

    let statusItem = NSStatusBar.system().statusItem(withLength: -2)
    var mainViewController: MainViewController? = MainViewController()

    func applicationDidFinishLaunching(_ aNotification: Notification) {
        if let button = statusItem.button
        {
            button.action = #selector(AppDelegate.localButtonAction(sender:))
            button.sendAction(on: [NSEventMask.leftMouseDown, NSEventMask.rightMouseDown])
        }
    }

    func localButtonAction(sender: NSStatusBarButton) {
        mainViewController?.doSomething(sender: sender)
    }
}

(请注意'localButtonAction'方法,我希望其他人有更漂亮的方法来做到这一点)

MainViewController看起来像这样:

import Cocoa

class MainViewController: NSViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do view setup here.
    }

    @IBAction func doSomething(sender: NSStatusBarButton) {
        // Do something when NSButton is pressed
        let event:NSEvent! = NSApp.currentEvent!
        if (event.type == NSEventType.rightMouseDown)
        {
            print("Right mouse button down")
        }
        else if (event.type == NSEventType.leftMouseDown)
        {
            print("Left mouse button down")
        }
    }    
}

问题在于,就我所见,event永远不会是rightMouseDown类型。我可能做错了什么,我希望其他人可以做这个工作,但现在它至少编译并且是Swift 3.0语法(使用Xcode 8.0 - beta 6 :))

希望能帮到你@ixany