将按钮操作重定向到 Swift 中的另一个函数

Redirect button action to another function in Swift

这可能是一个简单的问题,但我是 Swift 的新手,不知道 google 适合哪些术语。

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

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

但是,我需要区分按钮的左键单击和右键单击,在我的例子中是 NSStatusBarButton。根据 this answer 的建议,我将以下内容写入我的 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 中给出了错误消息 'Expression resolves to an unused function'。我无法弄清楚如何在 customClickAction 函数中从 MainViewController class 正确调用函数 doSomething,或者等效地,如何重定向 [=19= 的操作] 通过 customClickActiondoSomething。如果这个问题对于 Swift 专家来说太微不足道了,我深表歉意,但我真的很绝望地想弄清楚这个问题。

编辑:

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

是有同样 Expression resolves to an unused function 问题的人提出的问题。在 his/her 的情况下,问题是调用函数时没有在函数后面加上 (),所以 stop 而不是 stop()(如果有意义的话)。

好的,现在我们知道编译器试图告诉我们什么,我们可以试着弄清楚如何解决它。

在你的情况下,问题是你需要向你的 doSomething 方法发送一个 sender 参数,并且该参数必须是 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)
        }
    }
}

希望对你有所帮助。

跟进您的编辑

你写

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.

可能我误解了这里的所有内容,但你为什么不 "just" 将 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")
    }
}
如果我这样做,

"Left mouse button down" 和 "Right mouse button down" 会出现在我的控制台中。

Swift 3 次更新

正如@ixany 在评论中所写:

Is it me or Swift 3? :) Seems that your solution needs to be updated to Swift 3 since I'm not able to adapt it using the current Xcode Beta

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

第一个问题是在给selector赋值的时候不能直接进入MainViewControllerdoSomething方法,所以加了一个"local"步骤说话。

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