Alex S
Alex S

Reputation: 582

How to pop view controllers from the stack without navigating to them

Basically, I have 3 view controllers, A, B and C. A and B both have a back button that pops the top view controller off the stack when the user navigates backwards. However, there is no option to go backwards once the user makes it to C and I want to pop A and B off the stack when this happens without actually navigating backwards to A and B, because this is causing issues with the back button elsewhere in the app because there are leftover elements on the stack. How do you recommend doing this?

I am not trying to navigate back to the popped view controllers.

Upvotes: 2

Views: 3788

Answers (4)

Arpit Dongre
Arpit Dongre

Reputation: 1713

You can delete A & B from navigation stack without navigating backwards like this:

let controllersInStack = self.navigationController?.viewControllers

for viewController in controllersInStack!{
    if( viewController.isKind(of: ViewControllerA) || viewController.isKind(of: ViewControllerB) ){
        viewController.removeFromParentViewController()
    }
}

Upvotes: 0

Aakash
Aakash

Reputation: 2269

Add this to your C view controller code,

override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)

    if let vc = self.storyboard?.instantiateViewController(withIdentifier: "vc") as? ViewController, self.navigationController?.viewControllers.count == 3, self.navigationController!.viewControllers[0].isKind(of: <#A_CLASS_OBJ#>), self.navigationController!.viewControllers[1].isKind(of: <#B_CLASS_OBJ#>) {

        let navVC = UINavigationController(rootViewController: vc)
        navVC.navigationBar.isHidden = true
        navVC.automaticallyAdjustsScrollViewInsets = false

        UIApplication.shared.delegate?.window??.rootViewController = navVC
        UIApplication.shared.delegate?.window??.makeKeyAndVisible()
    }
}

Upvotes: 0

Magoo
Magoo

Reputation: 2636

You can set the viewControllers property of your navigationController and if you'd like to animate that transition it's also possible too.

navigationController?.viewControllers = []

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

In your example, when you get to C you'd have

navigationController?.viewControllers = [self]

which would remove A and B from the stack once you've got to C.. you might have to put it in viewDidAppear but make sure you only do that once, unless you want it to flush the stack every time C ends up on the screen.

var initialLoad:Bool = true

override func viewDidLoad() {

    super.viewDidLoad()
}

override func viewDidAppear(animated: Bool) {

    super.viewDidAppear(animated)

    if initialLoad {
        initialLoad = false
        navigationController?.viewControllers = [self]
    }   
}

Alternatively when you're about to push to C you could try instead of pushViewController

let cViewController = CViewController()
navigationController?.setViewControllers([cViewController], animated: true)

and I believe that'll push you forward and then remove A and B from the stack. Sometimes depending on the current state of the stack that'll animate a pop though

Upvotes: 6

eNeF
eNeF

Reputation: 3280

You can also set your view controller 'C' as your rootViewController so whether you hit the return button from anywhere after your 'C' it will all fall to 'C'.

Upvotes: 0

Related Questions