0

I have a bunch of views and then a logout button, which logs the user out and takes them to the first view controller (a login/register screen). I tried doing this with a modal presentation, but it destroys my navigation, and I can't use a pop to root view controller because it is not the root view controller - I am at least 2 navigation controllers deep. How would I go about somehow displaying only the first one? I basically need it to act as if the app was just relaunched. Would unwind segues help in some way? Thanksthis is what I mean by messing up the navigation. The following view controllers now pop up, instead of (the following pic is from the actual first time launching the app) how it should look

matej hantabal
  • 151
  • 1
  • 4

2 Answers2

0

Supposing that you use a UINavigationController, you can use the UINavigationController.setViewControllers(_:animated:) method in combination with UINavigationController.viewControllers. The latter provides you an array of view controllers in the exact order they are stacked by the navigation controller, while the former can be used to alter the navigation stack. For instance, if you want to keep only the first 3 view controllers in the navigation stack:

guard let navigationController = self.navigationController else { return }
let viewControllersToKeep = navigationController.viewControllers.prefix(3)
navigationController.setViewControllers(viewControllersToKeep, animated: true)

Note: The animation performed by the navigation controller in this case is usually (I believe always, but not 100% sure) a push animation instead of pop, which might not be the desired one.

So if you want to make the navigation controller to perform a pop animation, then you should call pop until you reach the desired view controller, but the key is to animated a single pop. For the same example as above:

guard let navigationController = self.navigationController else { return }
let numberOfPops = navigationController.viewControllers.count - 3
for i in 0..<numberOfPops {
    let animated = i == 0
    navigationController.popViewController(animated: animated)
}

Hope this answers the question about popping to the desired view controller (you can detect your view controller by its type, then you can find out its index and use the logic above).

If you want to dismiss to the first presenting view controller, then you need to call UIViewController.dismiss(animated:completion:) on the first presenting view controller. dismiss method will behaves like this:

  1. If the view controller is presenting a view controller, then it will dismiss the presented view controller;
  2. If the view controller is not presenting any view controller, but it is presented by another view controller (i.e. has a parent view controller), then it will ask the parent view controller to dismiss it;
  3. If none of the above, it will do nothing.

So long story short, you need to call dismiss on the view controller that you want to be left on the screen.

Vlad Rusu
  • 1,414
  • 12
  • 17
0

I basically need it to act as if the app was just relaunched.

In this case, assigning the login/register screen controller to UIWindow.rootViewController seems to be the right option. This topic has been already covered here: Swift ios set a new root view controller

Artem Garmash
  • 154
  • 10