View生命周期之viewWill/DidAppear(), viewWill/DidDissappear() &解决问题Fatal error: Unexpectedly found nil

17 篇文章 0 订阅
12 篇文章 0 订阅
  • 发生顺序:viewDidLoad() -> viewWillAppear() -> viewDidAppear() -> viewWillDissappear() -> viewDidDisappear()
  • 有ViewController1和ViewController2.两个关系如下,点击click, view1 -> view2, 点击back, view2 -> view1

  • view1代码如下:

    class ViewController1: UIViewController {

        

        override func viewDidLoad() {

            super.viewDidLoad()

            print("VC1 viewDidLoad Called")

        }

        

        override func viewWillAppear(_ animated: Bool) {

            super.viewWillAppear(animated)

            print("VC1 viewWillAppear Called")

        }

        

        override func viewDidAppear(_ animated: Bool) {

            super.viewDidAppear(animated)

            print("VC1 viewDidAppear Called")

        }

        

        override func viewWillDisappear(_ animated: Bool) {

            super.viewWillDisappear(animated)

            print("VC1 viewWillDisappear Called")

        }

        

        override func viewDidDisappear(_ animated: Bool) {

            super.viewDidDisappear(animated)

            print("VC1 viewDidDisappear Called")

        }

    }

  • view2代码如下:

  • class ViewController2: UIViewController {

  •     

        @IBOutlet weak var label: UILabel!

         

        @IBAction func goBack(_ sender: UIButton) {

            dismiss(animated: true, completion: nil)

        }

        

        override func viewDidLoad() {

            super.viewDidLoad()

            

            label.text = "hello"

            

            print("VC2 viewDidLoad Called")

        }

        

        override func viewWillAppear(_ animated: Bool) {

            super.viewWillAppear(animated)

            print("VC2 viewWillAppear Called")

        }

        

        override func viewDidAppear(_ animated: Bool) {

            super.viewDidAppear(animated)

            print("VC2 viewDidAppear Called")

        }

        

        override func viewWillDisappear(_ animated: Bool) {

            super.viewWillDisappear(animated)

            print("VC2 viewWillDisappear Called")

        }

        

        override func viewDidDisappear(_ animated: Bool) {

            super.viewDidDisappear(animated)

            print("VC2 viewDidDisappear Called")

        }

    }

  • 从运行结果看,首先run,得到

  • VC1 viewDidLoad Called

    VC1 viewWillAppear Called

    VC1 viewDidAppear Called

  • 点击next,得到

    VC2 viewDidLoad Called

    VC1 viewWillDisappear Called

    VC2 viewWillAppear Called

    VC2 viewDidAppear Called

    VC1 viewDidDisappear Called

  • 点击back,得到

  • VC2 viewWillDisappear Called

    VC1 viewWillAppear Called

    VC1 viewDidAppear Called

    VC2 viewDidDisappear Called

  • 根据每个veiw出现和消失的时间,可根据自己需求在这些functions里实现不同功能,比如有一个常见的nil错误,就是当你从viewA跳转到viewB,当从A的数据传递过来要复制给B的UIlable, 你有可能得到如下错误Fatal error: Unexpectedly found nil while implicitly unwrapping an Optional value。

  • 这时候你也许会检查这个label是否存在,是否从页面B到outler之间建立了联系,如果检查没问题,那说明此事你在给label赋值的地方,你的label并没有被创建出来。通常这是因为你的视图控制器还没有加载它的视图层次结构。视图控制器只有在视图消息发送给它时才加载它的视图层次结构。在实际将视图层次结构放到屏幕上时,系统会这样做,这发生在prepareForSegue:sender:和viewWillAppear:已返回之后。

  • 因为你的VC还没有加载它的视图层次,你的输出口仍然是空的。

    所以你要做的就是将赋值这些代码,放在viewDidLoad()里。
  • 再讲一个应用,比如有一个欢迎页面和一个登陆界面,都被embedded进入navigation controller。如果你想要欢迎页面的navigation bar隐藏,因为挺丑,然后在登陆页面出现。你可以使用如下代码,在欢迎页面所对应的控制台里:

  • override func viewWillAppear(_ animated: Bool) {

            super.viewWillAppear(animated)

            navigationController?.navigationBar.isHidden = true

        }

        

        override func viewWillDisappear(_ animated: Bool) {

            super.viewWillDisappear(animated)

            navigationController?.navigationBar.isHidden = false

        }

  • 当欢迎页面即将出现时,我们隐藏 navigationBar.isHidden = true,当跳转到下一个页面,view即将消失的时候,我们将navigationBar召唤出来。所以在跳转到登陆页面的一瞬间,你就看到了navigationbar

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值