1
votes

Say I have view controllers A, B & C embedded in a navigation controller. From C, I present a new navigation controller for a separate logical flow but need to return back to A upon completion. So the app flow is as follows: A->B->C -- present new navigation controller modally -- D->E->F. Then go from F back to A.

I have set up an unwind segue, however, the unwind segue only takes me back to D even though I have set it up to return back to A.

How can I make it unwind all the way back to A? Am I missing something I don't see? Thank you.

Inside A:

    @IBAction func unwindToHome(segue:UIStoryboardSegue){}

Then I have control-dragged from F to its 'exit' and chose the unwind segue I created in A, and wrote this segue code:

    private let SEGUE_TO_HOME = "unwindToHome"
    performSegue(withIdentifier: SEGUE_TO_HOME, sender: nil)
2
What are D, E, F?El Tomato
actually, you got it @Rob ! I had it in D as well for some reason...Side question.. I have put a deinit method in all of the above view controllers. I only print the word gone in all of them. when it unwinds back to A, 'gone' is only printed twice. doesnt the unwind segue deallocate all instances?user7804097
@Rob thanks again, working on strong references now. If it matters to you I can accept an answer if you post oneuser7804097

2 Answers

1
votes

When you unwind, it should go back up the chain of view controllers, through all of those navigation controllers and modal presentations, to get all the way to the view controller that has this unwind action implemented.

Is it possible that unwindToHome occurs in any of these view controllers other than A? That's the only way I can see that the unwind action wouldn't sent you all the way back to A. I'm wondering if, for example, D has its own unwindToHome action (or perhaps is another instance of the same type as A). Bottom line, I cannot reproduce the behavior you describe except through something like that.

You subsequently asked:

I have put a deinit method in all of the above view controllers. I only print the word gone in all of them. when it unwinds back to A, 'gone' is only printed twice. Doesn't the unwind segue deallocate all instances?

Yes, they should all be deallocated. If not, the “debug memory graph” debug memory graph button (see https://stackoverflow.com/a/30993476/1271826) is excellent at showing what is keeping a strong reference to the ones that are not deallocated. Most likely, these un-deallocated view controllers have some lingering strong reference cycle, repeating timer reference, or something like that which is keeping a strong reference to each, respectively.

0
votes

You could simply create a reference to the first navigation controller that controllers A-C are embedded in by creating a subclass for the second nav controller.

class SecondNavController: UINavigationController {

  // getter for previous nav controller
  var prevNavController: UINavigationController? {
    return parent?.navigationController
  }

}

and when you need to unwind, simply:

class FController: UIViewController {

  // other code

  func unwindToRootController() {
    guard let navController = navigationController as? SecondNavController,
      let prevNavController = navController.prevNavController else {
      return
    }
    navigationController.popToRootViewController(animated: true)
  }

}