将按钮操作重定向到 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= 的操作] 通过 customClickAction
到 doSomething
。如果这个问题对于 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
赋值的时候不能直接进入MainViewController
的doSomething
方法,所以加了一个"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
这可能是一个简单的问题,但我是 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= 的操作] 通过 customClickAction
到 doSomething
。如果这个问题对于 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
赋值的时候不能直接进入MainViewController
的doSomething
方法,所以加了一个"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