The strategy to go back to your initial view controller could vary depending on your view controllers are stacked.
There could be multiple scenarios and depending on your situation, you can decide which approach is the best.
Scenario 1
- Navigation controller is set as the root view controller
- Navigation controller sets View Controller A as the root
- Navigation controller pushes View Controller B
- Navigation controller pushes View Controller C
This is a straightforward scenario where navigationController?.popToRootViewController(animated:true)
is going to work from any view controller and return you back to View Controller A
Scenario 2
- Navigation controller is set as the root view controller
- Navigation controller sets View Controller A as the root
- View Controller A presents View Controller B
- View Controller B presents View Controller C
This scenario can be solved by the answers above
self?.view.window?.rootViewController.dismiss(animated: true)
and will bring you back to View Controller A
Scenario 3
- Navigation controller 1 is set as the root view controller
- Navigation controller 1 sets View Controller A as the root
- Navigation controller 1 pushes View Controller B
- View Controller B presents Navigation Controller 2
- Navigation Controller 2 sets View Controller D as the root
- Navigation controller 2 pushes View Controller E
Now imagine that you need to go from View Controller E all the way back to A
Using the 2 answers above will not solve your problem this time as popping to root cannot happen if the navigation controller is not on the screen.
You might try to add timers and listeners for dismissing of view controllers and then popping which can work, I think there was an answer like this above with a function dismissPopAllViewViewControllers
- I notice this leads to unusual behavior and with this warning Unbalanced calls to begin/end appearance transitions for
I believe what you can do to solve such scenarios is to
- start by presenting your modal views controllers from the navigation controller itself
- now you have better control to do what you want
So I would change the above to this architecture first:
- Navigation controller 1 is set as the root view controller (same)
- Navigation controller 1 sets View Controller A as the root (same)
- Navigation controller 1 pushes View Controller B (same)
- Navigation controller 1 presents Navigation Controller 2 (change)
- Navigation Controller 2 sets View Controller D as the root (same)
- Navigation controller 2 pushes View Controller E (same)
Now from View Controller E, if you add this:
let rootViewController = self?.view.window?.rootViewController as? UINavigationController
rootViewController?.setViewControllers([rootViewController!.viewControllers.first!],
animated: false)
rootViewController?.dismiss(animated: true, completion: nil)
you will be transported all the way back to View Controller A without any warnings
You can adjust this based on your requirements but this is the concept on how you can reset a complex view controller hierarchy.