问题描述
在项目中,有时会交换根视图控制器以重新创建整个窗口层次结构。只需使用
即可调用漂亮的标准代码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 (将#修改为@)