I've noticed that, when using the long-press back button feature in iOS 14, any properties relating to UINavigationController's view controller stack (.viewControllers, .topViewController, etc.) seem incorrect. Specifically, the order is reversed.
Regarding the .viewControllers property, Apple's docs state:
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.
If I've got three view controllers in a nav stack like as follows
[ViewController01, ViewController02, ViewController03] and print out the .viewControllers property in viewWillAppear, I get the expected output of:
[ViewController01]
[ViewController01, ViewController02]
[ViewController01, ViewController02, ViewController03]
If I tap the back button from ViewController03, I get the expected output from viewWillAppear in ViewController02:
[ViewController01, ViewController02]
However, if I set everything up again so I've got [ViewController01, ViewController02, ViewController03] and then use the long-press back button feature to jump back to ViewController01, I get the unexpected output of:
[ViewController03, ViewController01]
From viewWillAppear in ViewController01.
I'm not expecting this because ViewController03 isn't, and never was, the root view controller of the navigation stack. As per the docs, I'm expecting:
[ViewController01, ViewController03]
Could someone please let me know if this is expected behaviour or if I've overlooked something super-obvious?
Thank you!
I've reproduced this in a small sample app based on a "single view controller" project. Just embed the initial view controller in a nav stack and include the following:
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 {
}
(I'm aware the above is very horrible)