这是一个简单的界面实例。
1. 懒加载
大多数情况下View都是懒加载的,这样你不必在初始化控制器时去初始化View,并且代码更加紧凑了。
OC使用懒加载一般是在getter方法中进行处理,当_ivar == nil时,_ivar == XX.new,Swift中懒加载准确来说是延时加载,只会加载一次,如果置空便无法再次像OC哪样重新懒加载,除非添加变量使用和OC一样的方法进行处理。
- Objective-C懒加载:
- (UILabel *)label {
if (!_label) {
_label = UILabel.new;
}
return _label;
}
- Swift懒加载:
lazy var label: UILabel = {
return UILabel()
}()
- Swift仿Objective-C可多次加载的懒加载(以计算属性的方式完成):
var _label: UILabel?
var label: UILabel = {
if _label == nil {
_label = UILabel()
}
return _label!
}()
2. 初始化控制器
2.1 Swift初始化可以调用init()
或者直接使用类型名+()
的方式调用
例如UIViewController.init()
等价于UIViewController()
2.2 重写或添加初始化方法
- 无论重写还是添加新的初始化方法,都必须调用designed 方法,例如
ViewController
添加了init(fps:)
方法,该方法内部则必须调用UIViewController.init(nibName:bundle:)
- 如果父类实现了
init(coder:)
,则必须实现该方法,编译器会提醒,点击插入该代码,代码布局一般是直接返回nil - 初始化方法没有返回值,除非是
init?(...)
返回可选值的初始化方法允许返回nil。 - 子类的属性未初始化完毕前不可使用
super
,自身初始化完毕前不可使用self.xxx
, - 可选值可以不初始化,默认为
nil
,所有属性均可在属性那里直接初始化
class ViewController: UIViewController {
lazy var label: UILabel = {
let view = UILabel()
return view
}()
let fps: UInt
var index = 0
var delegate: Any?
init(fps: UInt) {
self.fps = fps
super.init(nibName: nil, bundle: nil)
}
required init?(coder: NSCoder) {
return nil
}
}
上方代码中
index
在属性声明时已初始化为0
,通过字面量推断为Int
类型delegate
为Any
可选类型,初始值为nil
3.label
懒加载,为UILabel
有值类型init(fps:)
调用了UIViewController.init(nibName:bundle:)
,在调用super
前所有属性均初始化完毕- 父类实现了
init(coder:)
,故子类也需要实现。
3. 简单布局
Swift和OC使用框架的方式几乎完全相同,这里列出相关代码。
class ViewController: UIViewController {
lazy var label: UILabel = {
let view = UILabel()
view.textColor = .black
view.textAlignment = .center
view.font = .systemFont(ofSize: 15)
return view
}()
let fps: UInt
var index = 0
var delegate: Any?
init(fps: UInt) {
self.fps = fps
super.init(nibName: nil, bundle: nil)
}
required init?(coder: NSCoder) {
return nil
}
deinit {
print("ViewController deinit")
}
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(label)
label.text = "Hello World"
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
label.center = view.center
}
}
4. 回调
在OC中,有block,delegate,notication
三种方式进行消息传递,在Swift中也同样支持。
protocol TextFieldDelegate: NSObjectProtocol {
func textField(_ textField: TextField, test: Any?) -> Void
}
class TextField: UITextField {
weak var my_delegate: TextFieldDelegate?
typealias Handle = (() -> ())
var handle: Handle?
init(handle: Handle?) {
self.handle = handle
super.init(frame: .zero)
}
required init?(coder: NSCoder) {
return nil
}
}
class ViewController: UIViewController, TextFieldDelegate {
lazy var textField: TextField = {
let view = TextField(handle: {
print("Pikachu")
})
view.textColor = .black
view.font = .systemFont(ofSize: 15)
view.my_delegate = self
return view
}()
let fps: UInt
var index = 0
var delegate: Any?
init(fps: UInt) {
self.fps = fps
super.init(nibName: nil, bundle: nil)
}
required init?(coder: NSCoder) {
return nil
}
deinit {
print("ViewController deinit")
NotificationCenter.default.removeObserver(self)
}
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(textField)
textField.placeholder = "Hello World"
NotificationCenter.default.addObserver(self,
selector: #selector(keyboardWillShow(_:)),
name: UIControl.keyboardWillShowNotification,
object: nil)
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
textField.frame = .init(x: 10, y: 100, width: 200, height: 40)
}
@objc func keyboardWillShow(_ noti: Notification) {
}
func textField(_ textField: TextField, test: Any?) {
}
}
上面的代码中
- TextFieldDelegate协议声明了一个方法
textField (_:test:)
- TextField有一个无参无返回值的闭包
- 监听了键盘将要出现的通知
这和OC的使用方法是完全一样的。
网友评论