我注意到,在 iOS 14 中使用长按后退按钮功能时,与 UINavigationController
的 View Controller 堆栈(.viewControllers
, .topViewController
等)似乎不正确。具体来说,顺序是颠倒的。
关于 .viewControllers
属性,Apple 的文档状态:
The root view controller is at index 0 in the array, the back view controller is at index n-2, and the top controller is at index n-1, where n is the number of items in the array.
如果我在导航堆栈中有三个 View Controller ,如下所示
[ViewController01, ViewController02, ViewController03]
并打印出 viewWillAppear
中的 .viewControllers
属性,我得到预期的输出:
[ViewController01]
[ViewController01, ViewController02]
[ViewController01, ViewController02, ViewController03]
如果我点击 ViewController03
的后退按钮,我会从 ViewController02
中的 viewWillAppear
获得预期的输出:
[ViewController01, ViewController02]
但是,如果我重新设置所有内容,得到 [ViewController01, ViewController02, ViewController03]
,然后使用长按后退按钮功能跳回到 ViewController01
,我得到了以下的意外输出:
[ViewController03, ViewController01]
来自 ViewController01
中的 viewWillAppear
。
我没想到会这样,因为 ViewController03
不是,也从来不是导航堆栈的 Root View Controller 。根据文档,我期望:
[ViewController01, ViewController03]
有人可以告诉我这是预期的行为还是我忽略了一些非常明显的事情?
谢谢!
我已经在一个基于“单 View Controller ”项目的小型示例应用程序中重现了这一点。只需将初始 View Controller 嵌入导航堆栈并包含以下内容:
class StubViewController: UIViewController {
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
print("\(self) will appear. Current nav stack follows:")
print("\(self.navigationController?.viewControllers ?? [])")
}
}
class ViewController: StubViewController {
override func viewDidLoad() {
super.viewDidLoad()
self.navigationController?.pushViewController(TestViewController01(), animated: true)
}
}
class TestViewController01: StubViewController {
override func viewDidLoad() {
super.viewDidLoad()
self.navigationController?.pushViewController(TestViewController02(), animated: true)
}
}
class TestViewController02: StubViewController {
override func viewDidLoad() {
super.viewDidLoad()
self.navigationController?.pushViewController(TestViewController03(), animated: true)
}
}
class TestViewController03: StubViewController {
}
(我知道上面的内容很可怕)
最佳答案
基本上,这里发生的事情是您无意中看到了香肠工厂的内部,并且看到了香肠是如何制作的。而且它不漂亮...!
解决方法是:不要那样做。在你查看它之前给 View Controller 堆栈一个安顿下来的机会:
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
DispatchQueue.main.async {
print("\(self) will appear. Current nav stack follows:")
print("\(self.navigationController?.viewControllers ?? [])")
}
}
更简单:只需将代码移动到 viewDidAppear
。
关于ios - 在 iOS 14 中使用 "long press back button"功能时,UINavigationController View Controller 堆栈顺序不正确,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65184222/