Swift,与 UIBarButtonItem 混淆
Swift, confusion with UIBarButtonItem
我最近开始学习Swift。当我尝试制作我的第一个 App
时,我对 UIBarButtonItem
感到困惑。如果我将 let UIBarButtonItem
初始化放在 viewDidLoad()
函数之外,当我按下 Next 按钮时什么也不会发生。
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()
函数之外,并在 viewController
中添加一个 UITextField
时, rightBarButton
如果我在按下按钮之前触摸 textfield
就可以工作。
这让我很困惑。机制是什么?
import UIKit
class ViewController: UIViewController {
var btnName = UIButton()
override func viewDidLoad() {
super.viewDidLoad()
btnName.setImage(UIImage(named: "imagename"), for: .normal)
btnName.frame = CGRect(x:0,y: 0,width: 30,height: 30)
btnName.addTarget(self, action: #selector(addTargetActionForButton(:_)), for: .touchUpInside)
let rightBarButton = UIBarButtonItem(customView: btnName)
self.navigationItem.rightBarButtonItem = rightBarButton
}
func addTargetActionForButton(_ sender : UIButton){
}
}
你正在将 let 变量带出 viewDidLoad 你不能带 let 全局变量。如果你想要 let 而不是你需要在 viewDidLoad 中声明。更多信息 let 和 var 检查这个 link What is the difference between `let` and `var` in swift?
override func viewDidLoad() {
let rightBarButton: UIBarButtonItem = UIBarButtonItem(title: "Next", style: .plain, target: self, action: #selector(onClickNext(button:)))
super.viewDidLoad()
self.view.backgroundColor = .white
self.navigationItem.rightBarButtonItem = rightBarButton
}
好吧,也许您不知道 ViewController 在内部是如何工作的。
首先,viewDidLoad
是您通常设置或初始化任何视图或视图属性 的区域。此方法在视图控制器对象的生命周期中也只被调用一次。这意味着 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 有一个您想要使用的对象并且将会使用的区域有一个 class 全局范围,但是当加载视图层次结构时将添加其余功能(意味着该对象不依赖于自身,例如,将目标添加到按钮时,您指的是self 内部的方法)...此变量或常量称为 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).
最后,你有一个 lazy stored 属性 也许可以应用到你想要的东西:
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.
解决方案: 创建一个惰性变量存储 属性 或者在 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:)))
}
UIBatButtonItem 可能包含 UIButton
上面的示例图像有 UINavigationItem,其中包含 LeftBarButtonItems ([UIBarButton]) 和 RightBarButtonItems([UIBarButtonItem]),每个 UIBarButtonItem 包含 UIButton
我们可以自定义UIButton来指定在View中的显示方式
我们可以将按钮操作直接连接到 UIButton
我最近开始学习Swift。当我尝试制作我的第一个 App
时,我对 UIBarButtonItem
感到困惑。如果我将 let UIBarButtonItem
初始化放在 viewDidLoad()
函数之外,当我按下 Next 按钮时什么也不会发生。
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()
函数之外,并在 viewController
中添加一个 UITextField
时, rightBarButton
如果我在按下按钮之前触摸 textfield
就可以工作。
这让我很困惑。机制是什么?
import UIKit
class ViewController: UIViewController {
var btnName = UIButton()
override func viewDidLoad() {
super.viewDidLoad()
btnName.setImage(UIImage(named: "imagename"), for: .normal)
btnName.frame = CGRect(x:0,y: 0,width: 30,height: 30)
btnName.addTarget(self, action: #selector(addTargetActionForButton(:_)), for: .touchUpInside)
let rightBarButton = UIBarButtonItem(customView: btnName)
self.navigationItem.rightBarButtonItem = rightBarButton
}
func addTargetActionForButton(_ sender : UIButton){
}
}
你正在将 let 变量带出 viewDidLoad 你不能带 let 全局变量。如果你想要 let 而不是你需要在 viewDidLoad 中声明。更多信息 let 和 var 检查这个 link What is the difference between `let` and `var` in swift?
override func viewDidLoad() {
let rightBarButton: UIBarButtonItem = UIBarButtonItem(title: "Next", style: .plain, target: self, action: #selector(onClickNext(button:)))
super.viewDidLoad()
self.view.backgroundColor = .white
self.navigationItem.rightBarButtonItem = rightBarButton
}
好吧,也许您不知道 ViewController 在内部是如何工作的。
首先,viewDidLoad
是您通常设置或初始化任何视图或视图属性 的区域。此方法在视图控制器对象的生命周期中也只被调用一次。这意味着 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 有一个您想要使用的对象并且将会使用的区域有一个 class 全局范围,但是当加载视图层次结构时将添加其余功能(意味着该对象不依赖于自身,例如,将目标添加到按钮时,您指的是self 内部的方法)...此变量或常量称为 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).
最后,你有一个 lazy stored 属性 也许可以应用到你想要的东西:
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.
解决方案: 创建一个惰性变量存储 属性 或者在 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:)))
}
UIBatButtonItem 可能包含 UIButton
我们可以自定义UIButton来指定在View中的显示方式 我们可以将按钮操作直接连接到 UIButton