【问题标题】:How to set the action for a UIBarButtonItem in Swift如何在 Swift 中为 UIBarButtonItem 设置动作
【发布时间】:2014-08-29 18:01:33
【问题描述】:

如何在 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")

【问题讨论】:

  • 您只需将选择器放入字符串action: "sayHello" 即可快速传递选择器
  • 非常感谢。我迫于压力要解决这个问题并且感到沮丧。
  • 此问题之前被标记为与@selector() in Swift? 重复。但是,这个问题专门询问 UIBarButtonItem 而另一个没有。要求初学者概括 selector 的所有用法对他们来说可能很困难,所以我删除了重复状态,以便人们可以及时更新这个问题。

标签: ios swift action uibarbuttonitem


【解决方案1】:

Swift 4/5 示例

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

@objc func buttonClicked(sender: UIBarButtonItem) {
        
}

【讨论】:

  • 这是对的,对于 Swift 4 你需要在函数声明中添加@objc。在 Swift 4 之前,这是隐式推断的。
  • button.target = self
  • @Mahesh 不需要设置目标
  • @norbDEV 目标需要 Swift 5
【解决方案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")
}

【讨论】:

    【解决方案3】:

    斯威夫特 5

    如果您在 Interface Builder 中创建了 UIBarButtonItem 并且您将出口连接到项目并希望以编程方式绑定选择器。

    别忘了设置目标和选择器。

    addAppointmentButton.action = #selector(moveToAddAppointment)
    addAppointmentButton.target = self
    
    @objc private func moveToAddAppointment() {
         self.presenter.goToCreateNewAppointment()
    }
    

    【讨论】:

      【解决方案4】:

      希望这篇文章能多一点帮助

      假设如果您想在单独的文件中制作条形按钮(用于模块化方法)并希望将选择器返回给您的视图控制器,您可以这样做:-

      您的实用程序文件

      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。

      感谢阅读

      【讨论】:

        【解决方案5】:

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

        Swift 3 及更高版本:

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

        如果您不确定方法名称应该是什么样子,有一个特殊版本的复制命令非常有用。将光标放在基本方法名称的某处(例如 sayHello),然后按 Shift+Control+Option+C .这会将“符号名称”放在要粘贴的键盘上。如果您还按住 Command,它将复制“限定符号名称”,其中也将包含类型。

        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

        【讨论】:

        • 只是说action函数不能是private!我不太清楚为什么,但如果我提供了一些私有函数的名称,我总是会收到错误
        • 我得到了这个:“没有实现 methodSignatureForSelector”
        • @AlamoPS 如果您使用带有冒号的第二个版本,您需要确保函数参数类型与您正在处理的任何操作相匹配。
        • @RyanForsyth 无论如何,字符串实际上在幕后被 Swift 翻译成 Selector("sayHello")
        • 这个答案已经过时了。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-06-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-01-20
        相关资源
        最近更新 更多