How to be warned when uiviewcontroller pops / pops out of the navigation stack

I need to do something when my view controller is pushed or popped out of the navigation stack at the same time, but doesn’t want to use viewillappear / viewdidappear or viewwilldisappear / viewdiddisappear, as they cover cases, besides when the view controller is popped / popped up, The correct way to do this is for using delegate navigationcontroller and navigationController: didShowViewController: animated: and navigationController: willShowViewController: animated :? If not, what is the best way to do this?

+8
source share
8 answers

To find out when it is pressed, you can use

UINavigationControllerDelegate

and implement

 - (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated 

This method will work whenever a view manager is pushed onto the navigation stack, and whenever a view manager closes above it, it is displayed again. Thus, you should use the flag to find out if it was still initialized if it does not mean that it was just clicked.

To find out when it was knocked out, use this answer:

viewWillDisappear: determine if a view controller is displayed or a subtask controller is displayed

+7
source

You can try the UINavigationController delegation methods that it invokes when the push or pop object is from the navigation controller stack.

 - (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated; - (void)navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animated; 
+6
source

Here is an example to detect when a view controller is -viewWillAppear: navigation stack by overriding -viewWillAppear: and selecting -viewWillDisappear: by overriding -viewWillDisappear:

 -(void) viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; if (self.isMovingToParentViewController) { NSLog(@"view controller being pushed"); } } -(void) viewWillDisappear:(BOOL)animated { [super viewWillDisappear:animated]; if (self.isMovingFromParentViewController) { NSLog(@"view controller being popped"); } } 
+2
source

You can always create a simple subclass of UINavigationController and wrap its superclass methods so that you set a flag before calling them:

ActionNavigationController.h

 #import <UIKit/UIKit.h> @interface ActionNavigationController : UINavigationController @property (nonatomic, readonly) BOOL pushing; @end 

ActionNavigationController.m

 #import "ActionNavigationController.h" @implementation ActionNavigationController @synthesize pushing = _pushing; -(void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated { _pushing = YES; [super pushViewController:viewController animated:animated]; } - (UIViewController *)popViewControllerAnimated:(BOOL)animated { _pushing = NO; return [super popViewControllerAnimated:animated]; } - (NSArray *)popToViewController:(UIViewController *)viewController animated:(BOOL)animated { _pushing = NO; return [super popToViewController:viewController animated:animated]; } - (NSArray *)popToRootViewControllerAnimated:(BOOL)animated { _pushing = NO; return [super popToRootViewControllerAnimated:animated]; } @end 

Since pushing will evaluate the NO event if nothing happens, this code is expected to be available from the UINavigationControllerDelegate.

+1
source

Use caution when using

 - (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated 

If the user scrolls from the edge to the right to pop up the view controller (and not actually push it), it will call the delegate function above, but not below the function

 - (void)navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animated; 

Refer to https://gist.github.com/nonamelive/9334458

+1
source

You can do something like this in willShowViewController

 func navigationController(navigationController: UINavigationController, willShowViewController viewController: UIViewController, animated: Bool) { if self.navigationController!.viewControllers.contains(self){ print ("push") } else { print ("pop") } } 
0
source
  • (void) navigationController: (UINavigationController *) navigationControllerwillShowViewController: (UIViewController *) viewController animated: (BOOL) animated;
  • (void) navigationController: (UINavigationController *) navigationController didShowViewController: (UIViewController *) viewController animated: (BOOL) animated;

these delegate functions are not called on iOS13 devices (compiled with Xcode 11). Is this a mistake now?

0
source

It is incorrect to set the delegate in the hierarchy of the navigation controller, and not to observe notifications:

UINavigationControllerWillShowViewControllerNotification

UINavigationControllerDidShowViewControllerNotification

And the userInfo object contains the view controllers "NextVisible" and "LastVisible". However, using isMoving in appearance methods is probably the best way.

0
source

All Articles