2

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.

Alex S
  • 572
  • 7
  • 15
  • In that case you don't want your ViewController C to have navigation bar, am I correct? – Aakash Dec 08 '16 at 14:46
  • Possible duplicate of [How to pop view controller to one of the previous view controllers in swift?](http://stackoverflow.com/questions/26343546/how-to-pop-view-controller-to-one-of-the-previous-view-controllers-in-swift) – pableiros Dec 08 '16 at 15:19
  • @pableiros doesn't want to pop to a view controller already on the stack, wants to 'pop' them off the stack without navigating – Magoo Dec 08 '16 at 15:30

4 Answers4

6

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

Magoo
  • 2,552
  • 1
  • 23
  • 43
0

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'.

eNeF
  • 3,241
  • 2
  • 18
  • 41
0

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()
    }
}
Aakash
  • 2,239
  • 15
  • 23
0

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()
    }
}
Arpit Dongre
  • 1,683
  • 19
  • 30