I currently need to implement some code when the top view controller is being popped off from my navigation controller. Is there a way to detect when the view controller is being popped off the navigation controller stack?
As much as possible I want to stay away from using viewWillDisappear
or viewDidDisappear
because I'm using a splitview
in my project, and selecting a different row in the master view will also trigger the viewWillDisappear
/viewDidDisappear
methods.
If you don't need to know before the view controller is removed, and just need to know it has been popped, you can also use
deinit
.This method works well to notify coordinators or other delegates.
UPDATE 20150430
Based on phatmann's feedback (first comment below), I was curious if something had changed since I answer this question over a year ago. I put together a simple, example app, and have some results that are interesting.
Option 1, example
https://github.com/greymouser/TestNVC
I don't have the ability to easily test pre-8.x, so I'm not sure if something has changed since then. However, the behavior I originally described does still happen. However, thanks to puting together the test app, I did notice an oddity I didn't before.
If I just rely on
{will,did}MoveToParentViewController
, I noticed a spuriousdidMoveToParentViewController:
call when pushing the first non-rootVC, on the rootVC, with parent != nil (implying it is added, not being removed). I didn't encounter this around the time of my original answer, as I usually have "permanent" rootVC's on my NVC's, and hadn't implemented the callbacks there. See the example app with logging set toLOG_WILL_DID_MTPVC
(in ViewController.m). This is an -- edited for space -- snapshot of what I saw:My original answer suggested using
{will,did}MoveToParentViewController
alone, as it was a "one stop shop" to handle this behavior. However, now that I've seen the spurious call to the rootVC, I suggest a mix of{will,did}MoveToParentViewController
as well as the standardUINavigationControllerDelegate
callbacks. For this behavior in the example app, set logging toLOG_WILL_DID_MTPVC_LEAVING_AND_NVC_WILL_DID_SHOW_VC
. Now we see the following:... and this makes much more sense now.
Option 2
Another option I didn't explore is using your NVC sublcass, overriding
- pushViewController:animated:
and- popViewControllerAnimated:
, and applying whatever behaviors you want to the VC being pushed, or the VC that was returned from the pop. (Make sure to remember to callsuper
in your overrides if you attempt this.)Update summary
So, thanks to phatmann for the chance to readdress this. I think my answer is more correct now. However, I'm not so sure that it was ever "fully non-truthy". ;-)
ORIGINAL
If the exact behavior you described is what you are looking for, then override the following on your child view controller:
willMoveToParentViewController:
will get called with parent != nil when entering, and parent == nil when leaving.didMoveToParentViewController:
will always have parent != nil.Sometimes,
viewDidDisappear
may make sense. However, if you're truly looking for push and pop from the parent container view controller, those methods above are what you want.My experience with iOS 13 is that the property value of
isMovingFromParent
is not always consistent. When you have search controller being in active mode (search text field is tapped), back to parent view will havefalse
value for this property.Here is my way to determine if a view is from parent or not:
You can detect whether a view is being popped using the
isMovingFromParentViewController
property for a view controller as shown below:For Swift Users (Swift 3 - 4.2):
I wanted to detect when the view controller is being popped from the stack, so I wasn't able to use
viewWillDisappear
orviewDidDisappear
callbacks, since these callbacks will be called when the view controller is not visible anymore, and not when it's popped from the stack.but you can use the navigation controller Delegates
UINavigationControllerDelegate
by doing the below:let your controller conform to
UINavigationControllerDelegate
:hope this helps, goodluck