为什么在窗口上交换根视图控制器时,在先前的根视图控制器上再次调用`viewDidAppear`方法?

问题描述

在项目中,有时会交换根视图控制器以重新创建整个窗口层次结构。只需使用

即可调用漂亮的标准代码
windows.rootViewController = newController

,但是此代码立即在即将被销毁的视图控制器上调用viewDidAppear。它仅在根视图控制器上调用。在viewDidAppear上经过一段时间后,正确调用了方法newController,但是为什么要在以前的视图控制器上调用它呢?

要提取问题,我创建了一个新项目,并添加了产生该问题的最少代码量。因此,如果您创建一个新项目并仅将自动生成的ViewController.swift修改为以下内容,就应该能够产生问题:

class ViewController: UIViewController {

    static var loadInstance: Int = 0
    var instance: Int = -1
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        ViewController.loadInstance += 1
        self.instance = ViewController.loadInstance
        
    }
    
    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        print("Calling did appear on instance: \(instance)")
        
        let controller = AnotherController()
        controller.modalPresentationStyle = .fullScreen
        controller.view.backgroundColor = UIColor.red
        present(controller,animated: true,completion: nil)
    }

}

class AnotherController: UIViewController {
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        view.addGestureRecognizer(UITapGestureRecognizer(target: self,action: #selector(onTap)))
    }
    
    @objc private func onTap() {
        print("Swapping root")
        UIApplication.shared.windows.first?.rootViewController = UIStoryboard(name: "Main",bundle: nil).instantiateInitialViewController()!
    }
}

根视图控制器需要提供至少一个其他视图控制器,该问题才能解决。它也需要全屏显示。

在此示例中,当您按屏幕时,将创建一个新的控制器,该控制器交换根并显示一个新的红色视图控制器。每次这样做,您都可以看到以前的根控制器报告viewDidAppear被调用的日志。日志如下所示:

Calling did appear on instance: 1
Swapping root
Calling did appear on instance: 1
Calling did appear on instance: 2
Swapping root
Calling did appear on instance: 2
Calling did appear on instance: 3

仅删除全屏设置会产生预期的结果:

Calling did appear on instance: 1
Swapping root
Calling did appear on instance: 2
Swapping root
Calling did appear on instance: 3

这是有原因还是仅仅是一个错误?无论如何:是否有解决方案,并且仍然可以安全地将viewDidAppear用于根控制器?

请注意,这只是该问题的最小介绍。实际的应用程序要复杂一些。

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...