Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Question about iOS 14 navigation stack management (different from iOS 13)

Tags:

ios

uikit

I've been testing our app on iOS and I've noticed a weird behaviour that happens on iOS 14, but it doesn't happen on iOS 13. It's regarding the navigation stack and how it works.

Say I have a navigation stack of [A, B, C], where C is of course the topmost view controller. I have a button in the C view controller which gets the navigation stack, removes C and then B, and finally it adds a new view controller D. Then I set the new stack to the navigation controller.

On iOS 13, the resulting stack is [A, D]. On iOS 14, the resulting stack is [C, A, D]. Somehow, it didn't let me remove the current view controller from the stack, but it did add to the bottom of the stack.

My only explanation has been that it has something to do with the new navigation history feature in iOS 14 (long hold on the Back button). Somehow this introduced some new constraints on the management of the navigation stack.

Hopefully someone can help me understand the new behaviour.

like image 634
Cristian Nicolae Avatar asked Aug 19 '20 11:08

Cristian Nicolae


2 Answers

I'm facing a similar issue in the latest iOS 14 as well - If I use setViewControllers:animated: on the UINavigationController, instead of replacing the nav stack entirely with the array of view controllers provided as an argument, it retains the current top most view controller, and pushes the new view controllers on top of it.

Basically, if your current view controller stack is:

[V1, V2, V3,... Vn]

and you use setViewControllers:animated with an argument of:

[X1, X2, X3,... Xn]

After the transition, your view controller stack will be:

[Vn, X1, X2, X3,... Xn]

This bug does not happen on iOS 13 and lower versions.

like image 122
Apoorv Khatreja Avatar answered Nov 03 '22 09:11

Apoorv Khatreja


It appears this was indeed an early beta issue and has been fixed in iOS 14 beta 6 / Xcode 12 beta 6.

let navigationController = UINavigationController(rootViewController: originalViewController)

navigationController.setViewControllers([replacementViewController], animated: true)

Inspecting the view controllers after calling setViewControllers

navigationController.viewControllers 

Now yields the expected results [replacementViewController] (matching the iOS 13 behavior).

like image 24
Kas Avatar answered Nov 03 '22 09:11

Kas