Search code examples
iosuiviewcontrolleruinavigationcontrolleruitabbarcontrollerpushviewcontroller

Better way to identify if a viewController was reached by popping the navigationController or using the tab-bar


Attempt to clarify: I would like to be able to differentiate between the two following scenarios:

  • a viewController's view becoming active as result of a pop.
  • a viewController's view becoming active as result of tabBar-navigation

In the app I'm working on I need to know if a viewController was presented due to its navigationController being popped or not. I had a look at this post and thought I had found the solution by simply calling:

BOOL wasReachedByPopping = !self.isMovingToParentViewController;

in my viewWillAppear: method

This works fine for most cases, but will unfortunately give a false positive when switching navigationControllers via a tabBarController. I've been thinking about adding a BOOL to my viewController called pushedNewController that will be set to YES prior to pushing.

self.pushedNewController = YES; // whenever I plan to push

This should work just fine, but I am really unhappy about having to base this on something as messy as long-lasting BOOL states. Anyone has a better approach to identify whether the viewController was reached by a pop or not?


Edit: I appreciate the effort below, but it seems they just offer the exact same functionality I already have. There are no methods there differentiating between being popped to or moved to through tab-bar-navigation. Seems I will have to settle on an internal BOOL to store whether the viewController requested a push or not. I set it up the following way, for anyone interested:

- (void)viewDidDisappear:(BOOL)animated{
    self.disappearedDueToPush = (self != [self.navigationController.viewControllers lastObject]);
}

Solution

  • So to recap, there seems to be no way outside storing the fact that the push was performed as a state. From the answers provided below, this state can be set by implementing the UINavigationControllerDelegate and using the navigationController:willShowViewController:animated:method:

    - (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated{
        self.disappearedDueToPush = !(viewController == self);
    }
    

    If implementing the delegate seems a bit heavy handed (it did to me) you might up the following in your viewDidDisappear method instead:

    if (self != [self.navigationController.viewControllers lastObject]){
        self.disappearedDueToPush = YES;
    }
    

    This made more sense to me as the reverse logic (and checking towards the fact) is performed in the viewWillAppear method.