loadView的调用和使用

2020-05-06  本文已影响0人  稀客花千树

1、什么时候被调用?

每次访问UIViewController的view(比如controller.view,self.view)而且view为nil,loadView方法都会被调用

2、有什么作用?

loadView方法是用来负责创建UIViewController的view

3、默认实现是怎么样的?

    override func loadView() {
        super.loadView() //这里做了两件事情:1、它会先去查找与当前视图控制器相关的xib文件,通过加载xib文件来创建视图控制的view 2、如果没有找到相关联的xib文件,就会创建一个空白的UIView,然后赋值给UIViewController的view属性  这里如果是用代码创建的UIViewController的view,不需要调用super.loadView() 如果调用了会造成一些不必要的开销
        let customView = CustomView()
        view = customView
    }

4、loadView使Swift视图代码更加简洁

问题一:我们在纯代码写View的时候会将所有相关代码都放进你的ViewController之中,这样会造成一个臃肿的ViewController

    override func viewDidLoad() {
        super.viewDidLoad()
        setAllView()

当然我们可以通过把view移动到不同的文件并添加引用到原来的ViewController之中来改善这样的情况但是你仍然需要用本不应该在 ViewController 中的内容填满 ViewController,就比如约束代码和其他设置 view 的代码 — 更不用说你现在有两个 view 属性(myView 和原生 view)在 ViewController 之中。
问题二:在MVVM的架构下,ViewController应该主要作为自身的View以及ViewModel之间的路由器--设置并且约束View并不是他们的职责,ViewController只应该起到前后传递信息的路由作用。这里也就是我们要让真正构建视图部分的代码和ViewController分离。而重写UIViewController中原生的View属性就能达到这样的效果

上代码:

class ViewController: UIViewController, HasCustomView{
    typealias CustomView = MyView


    override func loadView() {
        super.loadView() //这里做了两件事情:1、它会先去查找与当前视图控制器相关的xib文件,通过加载xib文件来创建视图控制的view 2、如果没有找到相关联的xib文件,就会创建一个空白的UIView,然后赋值给UIViewController的view属性  这里如果是用代码创建的UIViewController的view,不需要调用super.loadView() 如果调用了会造成一些不必要的开销
        view = CustomView()
    }
    override func viewDidLoad() {
        super.viewDidLoad()
        print("当loadView创建完View之后,此时View已经完成加载了,会调用viewDidLoad方法")
        customView.btn.addTarget(self, action: #selector(btnAction), for: .touchUpInside) // 这里拿到MyView中创建的button
    @objc func btnAction() {
        print("点击了按钮-----")
        self.present(LiveViewController(), animated: true, completion: nil)
    }
为了拿到MyView中的内容,创建一个CustomView协议,并在其中定义包含关联类型的行为
public protocol HasCustomView {
    associatedtype CustomView: UIView
}
extension HasCustomView where Self: UIViewController {
    public var customView: CustomView {
        guard let customView = view as? CustomView else {
            fatalError("Expected view to be of type \(CustomView.self) but got \(type(of: view)) instead")
        }
        return customView
    }
}
上一篇 下一篇

猜你喜欢

热点阅读