iOS中navigationController的后退buttoncallback

我将视图推到了导航控制器上,当我按下后退button时,它会自动转到上一个视图。 我想在按下返回button之前做一些事情,然后将视图从堆栈popup。 哪个是后退buttoncallback函数?

William Jockusch的答案用简单的方法解决了这个问题。

-(void) viewWillDisappear:(BOOL)animated { if ([self.navigationController.viewControllers indexOfObject:self]==NSNotFound) { // back button was pressed. We know this is true because self is no longer // in the navigation stack. } [super viewWillDisappear:animated]; } 

在我看来是最好的解决scheme。

 - (void)didMoveToParentViewController:(UIViewController *)parent { if (![parent isEqual:self.parentViewController]) { NSLog(@"Back pressed"); } } 

但它只适用于iOS5 +

重写后退button可能会更好,所以您可以在视图popup之前处理事件例如用户确认。

在viewDidLoad创build一个UIBarButtonItem并设置self.navigationItem.leftBarButtonItem它传入一个select

 - (void) viewDidLoad { // change the back button to cancel and add an event handler UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithTitle:@”back” style:UIBarButtonItemStyleBordered target:self action:@selector(handleBack:)]; self.navigationItem.leftBarButtonItem = backButton; [backButton release]; } - (void) handleBack:(id)sender { // pop to root view controller [self.navigationController popToRootViewControllerAnimated:YES]; } 

然后你可以做一些事情,比如提出一个UIAlertView来确认动作,然后popup视图控制器等。

或者不是创build一个新的后退button,您可以遵循UINavigationController委托方法来按下后退button时执行操作。

我结束了这个解决scheme。 当我们点击返回buttonviewDidDisappear的方法调用。 我们可以通过调用isMovingFromParentViewControllerselect器来检查哪一个返回true。 我们可以传回数据(使用委托).hope这个帮助某人。

 -(void)viewDidDisappear:(BOOL)animated{ if (self.isMovingToParentViewController) { } if (self.isMovingFromParentViewController) { //moving back //pass to viewCollection delegate and update UI [self.delegateObject passBackSavedData:self.dataModel]; } } 

对于“在popup视图之前”:

 - (void)willMoveToParentViewController:(UIViewController *)parent{ if (parent == nil){ NSLog(@"do whatever you want here"); } } 

有一个比问询viewControllers更合适的方法。 您可以让您的控制器成为具有后退button的导航条的代表。 这是一个例子。 在你想要处理按下后退button的控制器的实现中,告诉它它将实现UINavigationBarDelegate协议:

 @interface MyViewController () <UINavigationBarDelegate> 

然后在你的初始化代码中的某处(可能在viewDidLoad中)使你的控制器成为其导航栏的代表:

 self.navigationController.navigationBar.delegate = self; 

最后,实现shouldPopItem方法。 当后退button被按下时,这个方法被调用。 如果在堆栈中有多个控制器或导航项目,则可能需要检查哪些导航项目正在popup(项目参数),以便在您希望的时候只执行自定义内容。 这是一个例子:

 -(BOOL)navigationBar:(UINavigationBar *)navigationBar shouldPopItem:(UINavigationItem *)item { NSLog(@"Back button got pressed!"); //if you return NO, the back button press is cancelled return YES; } 

这是检测这个的正确方法。

 - (void)willMoveToParentViewController:(UIViewController *)parent{ if (parent == nil){ //do stuff } } 

这个方法在视图被推入的时候被调用。 所以检查parent == nil是从栈中popup视图控制器

如果您不能使用“viewWillDisappear”或类似的方法,请尝试子类UINavigationController。 这是头类:

 #import <Foundation/Foundation.h> @class MyViewController; @interface CCNavigationController : UINavigationController @property (nonatomic, strong) MyViewController *viewController; @end 

实现类:

 #import "CCNavigationController.h" #import "MyViewController.h" @implementation CCNavigationController { } - (UIViewController *)popViewControllerAnimated:(BOOL)animated { @"This is the moment for you to do whatever you want" [self.viewController doCustomMethod]; return [super popViewControllerAnimated:animated]; } @end 

另一方面,您需要将此viewController链接到您的自定义NavigationController,因此,在您的viewDidLoad方法中,您的常规viewController执行以下操作:

 @implementation MyViewController { - (void)viewDidLoad { [super viewDidLoad]; ((CCNavigationController*)self.navigationController).viewController = self; } } 

下面是我实现的另一种方式(没有用unwind segue来testing,但可能不会像其他人所说的那样,在这个页面上的其他解决scheme)使父视图控制器在子VC推入之前执行操作从视图堆栈中popup(我使用了这个从原来的UINavigationController开始的几个级别)。 这也可以用来在childVC被推动之前执行操作。 这具有使用iOS系统后退button的附加优点,而不必创build自定义的UIBarButtonItem或UIButton。

  1. 让你的父VC采用UINavigationControllerDelegate协议并注册委托消息:

     MyParentViewController : UIViewController <UINavigationControllerDelegate> -(void)viewDidLoad { self.navigationcontroller.delegate = self; } 
  2. MyParentViewController实现这个UINavigationControllerDelegate实例方法:

     - (id<UIViewControllerAnimatedTransitioning>)navigationController:(UINavigationController *)navigationController animationControllerForOperation:(UINavigationControllerOperation)operation fromViewController:(UIViewController *)fromVC toViewController:(UIViewController *)toVC { // Test if operation is a pop; can also test for a push (ie, do something before the ChildVC is pushed if (operation == UINavigationControllerOperationPop) { // Make sure it's the child class you're looking for if ([fromVC isKindOfClass:[ChildViewController class]]) { // Can handle logic here or send to another method; can also access all properties of child VC at this time return [self didPressBackButtonOnChildViewControllerVC:fromVC]; } } // If you don't want to specify a nav controller transition return nil; } 
  3. 如果在上面的UINavigationControllerDelegate实例方法中指定了特定的callback函数

     -(id <UIViewControllerAnimatedTransitioning>)didPressBackButtonOnAddSearchRegionsVC:(UIViewController *)fromVC { ChildViewController *childVC = ChildViewController.new; childVC = (ChildViewController *)fromVC; // childVC.propertiesIWantToAccess go here // If you don't want to specify a nav controller transition return nil; 

    }

如果你正在使用一个Storyboard,并且你是从一个push segue来的,你也可以重写shouldPerformSegueWithIdentifier:sender: