In my TabBarViewController
, I create a UINavigationController and present it as a modal.
var navController = UINavigationController() let messageVC = self.storyboard?.instantiateViewControllerWithIdentifier("MessagesViewController") as! MessagesViewController self.presentViewController(self.navController, animated: false, completion: nil) self.navController.pushViewController(messageVC, animated: false)
Inside my MessageViewController
, this is how I want to dismiss it:
func swipedRightAndUserWantsToDismiss(){ if self == self.navigationController?.viewControllers[0] { self.dismissViewControllerAnimated(true, completion: nil) //doesn't deinit }else{ self.navigationController?.popViewControllerAnimated(true) //deinits correctly } } deinit{ print("Deinit MessagesViewController") }
The problem is that when I get to the root View Controller and try to dismiss both the child and the UINavigationController, my MessagesViewController
deinit does not get called. Something's holding on to it -- most likely UINavigationController
When it comes time to dismiss a presented view controller, the preferred approach is to let the presenting view controller dismiss it. In other words, whenever possible, the same view controller that presented the view controller should also take responsibility for dismissing it.
VC3 -> present VC2 -> VC1 VC2 needs to be in a UINavigationController then after you present it you can push VC3. The back button will work as expected on VC3, for VC2 you should call dismiss when the back button is pressed. Try implementing some of that in code and then update your question.
Your controller hierarchy looks like this:
UITabViewController | | presents | UINavigationController | | contains view controllers | [root, MessagesViewController]
Now, if you are inside MessagesViewController
, then its navigationController
is the one that is being presented and that's the one you should be dismissing but calling dismiss
on MessagesViewController
should work too.
However, the problem is that dismissing the navigation controller won't remove its view controllers. It seems you are holding to your navigation controller (since you are presenting it using self.navController
) so the state will become
UITabViewController | | self.navController holds a reference to | UINavigationController | | contains view controllers | [root, MessagesViewController]
To properly destroy MessagesViewController
you will have to either let go of the navController
or you will have to pop to root (thus removing MessagesViewController
from view hierarchy).
The typical solution would be not to save a reference to navController
at all. You could always create a new UINavigationController
when presenting. Another solution is using a delegate - instead of dismissing from inside MessagesViewController
, let it call back to the presenter, which would call
self.navController.dismiss(animated: true) { self.navController = nil }
Try this
func swipedRightAndUserWantsToDismiss(){ self.navigationController.dismissViewControllerAnimated(false, completion:nil); }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With