2

This might be an easy question, but I am new to Swift and do not know for which terms to google for.

For a menu bar application, I have implemented a custom function called doSomething that works just fine when it is bound to some button:

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

However, I need to distinguish between left- and right click on the button, which in my case is a NSStatusBarButton. Following the suggestion from this answer, I have written the following into my 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
         }
    }
}

The above code snippet gives me the error message 'Expression resolves to an unused function' in XCode. I cannot figure out how to properly call the function doSomething from the MainViewController class within the customClickAction function, or equivalently, how to redirect the action of the statusItem.button via customClickAction to doSomething. I apologize if this question might seem too trivial for the Swift experts, but I am really in despair trying to figure this one out.

EDIT:

If the function customClickAction was not existing, I would simply write button.action = #selector(mainViewController?.show(_:)) in applicationDidFinishLaunching to call the function and everything works. However, part of my problem is that doing the same in my custom function would overwrite the binding once the left mouse button has been pressed for the first time.

4

1 回答 1

2

是遇到同样问题的人提出的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")
    }
}

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

斯威夫特 3 更新

正如@ixany 在评论中所写:

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

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

第一个问题是我无法直接进入分配时的doSomething方法,所以我添加了一个“本地”步骤可以这么说。MainViewControllerselector

现在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

于 2016-06-30T06:42:08.917 回答