如何解决为什么在窗口上交换根视图控制器时,在先前的根视图控制器上再次调用`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 举报,一经查实,本站将立刻删除。