如何在Swift中为UIBarButtonItem设置操作


86

如何在Swift中设置自定义UIBarButtonItem的操作?

以下代码将按钮成功放置在导航栏中:

var b = UIBarButtonItem(title: "Continue", style: .Plain, target: self, action:nil)
self.navigationItem.rightBarButtonItem = b

现在,我想func sayHello() { println("Hello") }在触摸按钮时打电话。到目前为止,我的努力:

var b = UIBarButtonItem(title: "Continue", style: .Plain, target: self, action:sayHello:)
// also with `sayHello` `sayHello()`, and `sayHello():`

和..

var b = UIBarButtonItem(title: "Continue", style: .Plain, target: self, action:@selector(sayHello:))
// also with `sayHello` `sayHello()`, and `sayHello():`

和..

var b = UIBarButtonItem(title: "Continue", style: .Plain, target: self, action:@selector(self.sayHello:))
// also with `self.sayHello` `self.sayHello()`, and `self.sayHello():`

请注意,它sayHello()出现在智能感知中,但不起作用。

谢谢你的帮助。

编辑:为后代,以下作品:

var b = UIBarButtonItem(title: "Continue", style: .Plain, target: self, action:"sayHello")

4
您只需将选择器放入字符串即可快速传递选择器,action: "sayHello"
Jiaaro

非常感谢。我承受着将其解决的压力,并且感到沮丧。
kmiklas 2014年

1
这个问题以前在Swift中被标记为@selector()的副本。但是,这个问题专门询问,UIBarButtonItem而另一个则不。要求初学者对的所有用法selector都一概而论,因此我要删除重复的状态,以便人们可以使此问题保持最新。
苏拉奇'16

Answers:


157

从Swift 2.2开始,针对编译时检查的选择器有一种特殊的语法。它使用语法:#selector(methodName)

Swift 3及更高版本:

var b = UIBarButtonItem(
    title: "Continue",
    style: .plain,
    target: self,
    action: #selector(sayHello(sender:))
)

func sayHello(sender: UIBarButtonItem) {
}

如果不确定方法名称应为什么样,则可以使用copy命令的特殊版本,该版本非常有用。将光标放在基本方法名称的某个位置(例如sayHello),然后按 Shift+ Control+ Option+ C。这样就可以在键盘上粘贴“符号名称”。如果还按住Command,它将复制“ Qualified Symbol Name”(合格符号名称),其中还将包括类型。

Swift 2.3:

var b = UIBarButtonItem(
    title: "Continue",
    style: .Plain,
    target: self,
    action: #selector(sayHello(_:))
)

func sayHello(sender: UIBarButtonItem) {
}

这是因为在进行方法调用时,在Swift 2.3中不需要第一个参数名称。

您可以在swift.org上了解有关语法的更多信息:https ://swift.org/blog/swift-2-2-new-features/#compile-time-checked-selectors


11
仅提及动作功能不能私有!我不太确定为什么,但是如果我提供了一些私有函数的名称,我总是会出错
maddob

我得到了这个:“未实现methodSignatureForSelector”
AlamoPS

1
@AlamoPS如果您将第二个版本与冒号一起使用,则需要确保函数参数类型与您要处理的任何操作相匹配。
杰森

1
@RyanForsyth实际上Selector("sayHello"),无论如何Swift都会将字符串转换为幕后。
fatuhoku

2
这个答案已经过时了。
Dan Loewenherz

33

Swift 4/5示例

button.target = self
button.action = #selector(buttonClicked(sender:))

@objc func buttonClicked(sender: UIBarButtonItem) {
        
}

5
没错,对于Swift 4,您需要添加@objc到函数声明中。直到Swift 4才隐式推断出这一点。
乔纳森·卡布雷拉

1
button.target = self
Mahesh

@Mahesh不需要设置目标
norbDEV

Swift 5
Biasi Wiga

2

Swift 5和iOS 13+编程示例

  1. 您必须使用标记功能@objc,请参见以下示例!
  2. 函数名称后没有括号!只需使用#selector(name)
  3. privatepublic无所谓;您可以使用私人。

代码示例

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    
    let menuButtonImage = UIImage(systemName: "flame")
    let menuButton = UIBarButtonItem(image: menuButtonImage, style: .plain, target: self, action: #selector(didTapMenuButton))
    navigationItem.rightBarButtonItem = menuButton
}

@objc public func didTapMenuButton() {
    print("Hello World")
}

0

希望这个能多一点帮助

让我们假设,如果您想将bar按钮制作在一个单独的文件中(用于模块化方法),并希望将选择器还给您的viewcontroller,则可以执行以下操作:

您的实用程序文件

class GeneralUtility {

    class func customeNavigationBar(viewController: UIViewController,title:String){
        let add = UIBarButtonItem(title: "Play", style: .plain, target: viewController, action: #selector(SuperViewController.buttonClicked(sender:)));  
      viewController.navigationController?.navigationBar.topItem?.rightBarButtonItems = [add];
    }
}

然后创建一个SuperviewController类,并在其上定义相同的函数。

class SuperViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
            // Do any additional setup after loading the view.
    }
    @objc func buttonClicked(sender: UIBarButtonItem) {

    }
}

并且在我们的基本viewController(继承您的SuperviewController类)中覆盖相同的函数

import UIKit

class HomeViewController: SuperViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.
    }

    override func viewWillAppear(_ animated: Bool) {
        GeneralUtility.customeNavigationBar(viewController: self,title:"Event");
    }

    @objc override func buttonClicked(sender: UIBarButtonItem) {
      print("button clicked")    
    } 
}

现在,只需在想要此barbutton的任何类中继承SuperViewController。

感谢您的阅读


0

迅捷5

如果您已UIBarButtonItem在Interface Builder中创建,并且已将插座连接到item并希望以编程方式绑定选择器。

不要忘记设置目标和选择器。

addAppointmentButton.action = #selector(moveToAddAppointment)
addAppointmentButton.target = self

@objc private func moveToAddAppointment() {
     self.presenter.goToCreateNewAppointment()
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.