Search code examples
iosswiftuinavigationcontrollerpoptoviewcontroller

popToViewController isn't popping all of the view controllers


So I have 3 view controllers: TableViewController, A, and B. The user is able to navigate to any view controller from any view controller.

When the user goes back and forth between A, and B view controllers I want them to be pushed onto the nav. stack. When the "home" button is pressed, I would like for the view controllers to all be popped back to the TableViewController using popToViewController, not popToRootViewController (for reasons).

I have partly working code that pops the last visited view controller, but now all the ones in between.

func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {

    if indexPath.row == 0 {
        if let navController = self.navigationController {
            for controller in navController.viewControllers {
                if controller is TableViewController {
                    navController.popToViewController(controller, animated: true)
                    break
                }
            }
        }
    } else {

        let vcName = identities[indexPath.row]
        let viewController = storyboard?.instantiateViewController(withIdentifier: vcName)
        self.navigationController?.pushViewController(viewController!, animated: true)
    }

}

I'm not sure why all the view controllers aren't being popped.

Code I use to check what's being pushed and popped:

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

    if self.isMovingToParentViewController {
        print("A is pushed")
    }
}

override func viewWillDisappear(_ animated: Bool) {
    super.viewWillDisappear(true)

    if self.isMovingFromParentViewController {
        print("A is popped")
    }
}

I'm also checking increase in memory.

I will provide more code/info in needed.

Any help would be greatly appreciated.


Solution

  • Your confusion may simply be the way you are trying to "check" that the VCs are "popped".

    Suppose you have gone:

    root->TableView->A->B->A->B->B->B->`
    

    At that point, the only VC that is visible is the last instance of A. So when you call

    navController.popToViewController(controller, animated: true)
    

    viewWillDisappear() will only be called on the last instance of A - none of the other VC instances will "disappear" because they are not visible.

    If you want to confirm the other VCs in the stack are being "removed", put this in each view controller:

    deinit() {
        print("I'm being removed:", self)
    }
    

    The other part of the question - do you want to animate through the process? So you would actually see the VCs "walk back up the stack"? If so, follow @FryAnEgg's link to Completion block for popViewController