10

I'm currently designing an application that has a funnel flow and a dashboard flow. I'd like the funnel flow to be cleared from memory on completion:

So if it goes 1) if new user start funnel -> 2) funnel screens 1-5 -> 3) funnel complete screen

I'd like to transition to dashboard screen which is not yet on the stack (it's not my head controller in this case). How can I clear the 6 screens above from memory when I transition to dashboard - basically setting a new navigation root and clearing the rest? An unwind segue doesn't appear to be able to set a new root destination.

3 Answers 3

13

If you only want to clear the navigation stack, and push a new view on top of it, there is an even simpler solution.

Let's suppose you already (programmatically) assigned a navigation controller, e.g. in a viewDidLoad() function, like:

let navController = UINavigationController( rootViewController: YourRootController )
view.addSubview( navController.view )
addChildViewController( navController )

navController.didMoveToParentViewController( self )

YourRootController acts as the stacks's root (the bottom of the stack).

To push other controllers on top of the stack (your funnel controllers), simply use navController.pushViewController( yourControllerInstance!, animated: false ).

If you want to clear the stack after completion of the funnel, just call:

navController.popToRootViewControllerAnimated( false )

This function removes all views (besides the root controller) from your stack.

Sign up to request clarification or add additional context in comments.

1 Comment

navController.popToRootViewController(animated: false) solved
3

So I ended up having to do it programmatically by popping back to the first controller and then replacing from the funnel head to the dashboard head:

func bookingCompleteAcknowledged(){
    //remove the popup controller
    dismissViewControllerAnimated(true, completion: nil)
    //remove current controller
    dismissViewControllerAnimated(true, completion: nil)

    if let topController = UIApplication.sharedApplication().keyWindow?.rootViewController {

        if let navcontroller = topController.childViewControllers[0] as? UINavigationController{
          navcontroller.popToRootViewControllerAnimated(false)

            if let funnelcontroller = navcontroller.childViewControllers[0] as? FunnelController {
                funnelcontroller.removeFromParentViewController();
                funnelcontroller.view.removeFromSuperview();

                let revealController = self.storyboard?.instantiateViewControllerWithIdentifier("DashboardController") as! SWRevealViewController

                navcontroller.addChildViewController(revealController)
                navcontroller.view.addSubview(revealController.view)
            }
        }
    }

}

Comments

0

I believe you can do this by simply assigning a new array (with just the dashboard view, in your case) to the UINavigationController's viewControllers property.

Why do you want to use the same navigation controller instead of making a new one? Generally, instead of trying to change the root of a navigation controller, I would recommend just creating a new navigation controller.

2 Comments

Hi Rschmidt, thanks for chiming in your thoughts. This may be my inexperience with Navigation controllers, but transitioning to a new nav controller still would use a show segue leaving the previously existing screens in memory, no?
Tbh I don't know because I do not use storyboards. I'm sure there's a way to have it removed from memory, otherwise that would be a extremely big flaw in storyboards.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.