我最近开始学习 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 ,如果我在按下按钮之前触摸 textfield ,rightBarButton 就会起作用。
这让我很困惑。机制是什么?
Best Answer-推荐答案 strong>
好吧,也许您错过了 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/
|