OGeek|极客世界-中国程序员成长平台

标题: ios - Swift,与 UIBarButtonItem 混淆 [打印本页]

作者: 菜鸟教程小白    时间: 2022-12-11 18:24
标题: ios - Swift,与 UIBarButtonItem 混淆

我最近开始学习 Swift。当我尝试制作我的第一个 App 时,我对 UIBarButtonItem 感到困惑。如果我把 UIBarButtonItem 初始化放在 viewDidLoad() 函数之外,当我按下 Next Button 时什么也不会发生。

class ViewController: UIViewController, UITextFieldDelegate {
    let rightBarButton: UIBarButtonItem = UIBarButtonItem(title: "Next", style: .plain, target: self, action: #selector(onClickNext(button))

    override func viewDidLoad() {
        super.viewDidLoad()
        self.view.backgroundColor = .white

        self.navigationItem.rightBarButtonItem = rightBarButton
    }

    func onClickNext(button: UIBarButtonItem) {
        print("should push view controller")
    }
}

但是,当我将initialization放入viewDidLoad()函数时,输出区确实输出了我在onClickNext(button: ) 函数。

class ViewController: UIViewController, UITextFieldDelegate {
    var rightBarButton: UIBarButtonItem?

    override func viewDidLoad() {
        super.viewDidLoad()

        self.view.backgroundColor = .white

        self.rightBarButton = UIBarButtonItem(title: "Next", style: .plain, target: self, action: #selector(onClickNext(button))
        self.navigationItem.rightBarButtonItem = rightBarButton
    }

    func onClickNext(button: UIBarButtonItem) {
        print("should push view controller")
    }
}

另外,我发现当我将 initialization 放在 viewDidLoad() 函数之外时,我将 UITextField 添加到 viewController,如果我在按下按钮之前触摸 textfieldrightBarButton 就会起作用。

这让我很困惑。机制是什么?



Best Answer-推荐答案


好吧,也许您错过了 ViewController 内部的工作方式。

首先,viewDidLoad 是您通常设置或初始化任何 View 或 View 属性的区域。此方法在 View Controller 对象的生命周期内也只调用一次。这意味着 self 已经存在。

了解这一点对于了解 let 属性的作用非常重要,(来自 Apple)

A constant declaration defines an immutable binding between the constant name and the value of the initializer expression; after the value of a constant is set, it cannot be changed. That said, if a constant is initialized with a class object, the object itself can change, but the binding between the constant name and the object it refers to can’t.

尽管上面的区域是你声明变量和常量的地方,通常是为了简单的初始化,它只是告诉 VC 有一个你想要使用的对象并且有一个类全局范围的区域,但是其余的功能将在 View 层次结构加载时添加(意味着对象不依赖于自身,例如,当向按钮添加目标时,您指的是自身内部的方法)....this变量或常量被称为 Stored Properties

In its simplest form, a stored property is a constant or variable that is stored as part of an instance of a particular class or structure. Stored properties can be either variable stored properties (introduced by the var keyword) or constant stored properties (introduced by the let keyword).

最后,你有一个惰性存储属性,也许可以应用到你想要的东西:

A lazy stored property is a property whose initial value is not calculated until the first time it is used. You indicate a lazy stored property by writing the lazy modifier before its declaration.

解决方案:创建一个惰性 var 存储属性或在 ViewDidLoad 中添加他的属性(当 self 已经存在时)

lazy private var doneButtonItem : UIBarButtonItem = {
    [unowned self] in
    return UIBarButtonItem(title: "Next", style:UIBarButtonItemStyle.Plain, target: self, action: #selector(onClickNext(button))
    }()

let rightBarButton: UIBarButtonItem?

override func viewDidLoad() {
        super.viewDidLoad()
        rightBarButton = UIBarButtonItem(title: "Next", style: .plain, target: self, action: #selector(onClickNext(button))
}

关于ios - Swift,与 UIBarButtonItem 混淆,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45408498/






欢迎光临 OGeek|极客世界-中国程序员成长平台 (http://jike.in/) Powered by Discuz! X3.4