【问题标题】:UIBarButtonItem action method does not work in certain casesUIBarButtonItem 操作方法在某些情况下不起作用
【发布时间】:2019-08-25 06:47:51
【问题描述】:

当前的问题和我想知道的事情

UIBarButtonItem 操作方法在某些情况下不起作用。我想知道为什么它不起作用。

案例1

case1 storyboard

刚刚将 NavigationController 添加到默认 ViewController 中

import UIKit

class ViewController: UIViewController {

    let okButton = UIBarButtonItem(title: "OK", style: .plain, target: self, action: #selector(okButtonTapped(_:)))

    override func viewDidLoad() {
        super.viewDidLoad()
        self.navigationItem.rightBarButtonItem = okButton
    }

    @objc func okButtonTapped(_ sender: UIBarButtonItem) {
        print("OK!")
    }
}

在这种情况下,确定按钮不起作用。 没有错误信息。

案例2

case2 storyboard

在默认 ViewController 中添加了导航栏。 UINavigationItem 连接到名为 myNavigationItem 的插座。

import UIKit

class ViewController: UIViewController {

    @IBOutlet weak var myNavigationItem: UINavigationItem!

    let okButton = UIBarButtonItem(title: "OK", style: .plain, target: self, action: #selector(okButtonTapped(_:)))

    override func viewDidLoad() {
        super.viewDidLoad()
        myNavigationItem.rightBarButtonItem = okButton
    }

    @objc func okButtonTapped(_ sender: UIBarButtonItem) {
        print("OK!")
    }
}

在这种情况下,确定按钮起作用。

总结

我知道即使在情况 1 中,如果在 viewDidLoad 中执行 okButton 初始化,它也会起作用。 我想知道为什么 case2 有效,但 case1 无效。

谢谢。

【问题讨论】:

    标签: ios swift


    【解决方案1】:

    如果在viewDidLoad 之前初始化okButton,则无法设置目标self。所以初始化viewDidLoad中的按钮

    class ViewController: UIViewController {
    
        var okButton:UIBarButtonItem?
    
        override func viewDidLoad() {
            super.viewDidLoad()
            okButton = UIBarButtonItem(title: "OK", style: .plain, target: self, action: #selector(okButtonTapped(_:)))
            self.navigationItem.rightBarButtonItem = okButton
        }
    
        @objc func okButtonTapped(_ sender: UIBarButtonItem) {
            print("OK!")
        }
    }
    

    【讨论】:

    • 或者让它成为惰性变量
    • 感谢您的回答。我还是有点不明白。为什么我不能只在案例1中将目标self设置在viewDidLoad之前。selfViewController的一个实例,对吧?
    • @capibara 因为 self 在 vi​​ewdidload 之前还没有初始化
    【解决方案2】:

    如果您需要整个类都可以访问该按钮,只需像您一样声明它,但在 viewDidLoad 中对其进行初始化。 案例 2 有效,因为情节提要在调用视图加载时为您提供了 myNavigationItem。在 viewDidLoad 中查看案例 1 中 self.navigationItem 的值。

    【讨论】:

      【解决方案3】:

      我总结了一下,因为我自己解决了。

      1. 在实例属性初始化期间,self 无法使用,因为尚未创建实例本身。但是,它被视为nil 而不会导致错误。这两种情况都是如此。
      2. 如果目标设置为nil,则当在视图层次结构中找到操作方法 (ngButtonTapped) 时将执行。
      3. 在case1中,导航栏上方没有ViewController,所以没有找到action方法,什么也没有发生。 (可以使用 Xcode 视图调试器确认 VIew 层次结构)
      4. 在案例 2 中,由于 ViewController 位于导航栏上方,因此执行操作方法 (ngButtonTapped)。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-11-28
        • 2011-09-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-11-01
        • 2018-12-17
        相关资源
        最近更新 更多