尝试在iOS中处理“返回”导航button操作

我需要检测用户点击导航栏上的“后退”button,以便在发生这种情况时执行某些操作。 我试图手动设置这样的button,这样的行动:

[self.navigationItem.backBarButtonItem setAction:@selector(performBackNavigation:)]; - (void)performBackNavigation:(id)sender { // Do operations [self.navigationController popViewControllerAnimated:NO]; } 

我首先将代码放在视图控制器本身,但是我发现self.navigationItem.backBarButtonItem似乎是nil ,所以我将相同的代码移动到父视图控制器,它将前者推到导航堆栈。 但我无法做到这一点。 我已经阅读了关于这个问题的一些post,其中一些人说,select器需要设置在父视图控制器,但对我来说它不工作呢…我做错了什么?

谢谢

使用VIewWillDisappear方法试试这个代码来检测按下NavigationItem的后退button:

 -(void) viewWillDisappear:(BOOL)animated { if ([self.navigationController.viewControllers indexOfObject:self]==NSNotFound) { // Navigation button was pressed. Do some stuff [self.navigationController popViewControllerAnimated:NO]; } [super viewWillDisappear:animated]; } 

或者有另一种方法来获得导航BAckbutton的动作。

为后退button的UINavigationItem创build自定义button。

例如:

在ViewDidLoad中:

 - (void)viewDidLoad { [super viewDidLoad]; UIBarButtonItem *newBackButton = [[UIBarButtonItem alloc] initWithTitle:@"Home" style:UIBarButtonItemStyleBordered target:self action:@selector(home:)]; self.navigationItem.leftBarButtonItem=newBackButton; } -(void)home:(UIBarButtonItem *)sender { [self.navigationController popToRootViewControllerAnimated:YES]; } 

Swift:

 override func willMoveToParentViewController(parent: UIViewController?) { if parent == nil { // Back btn Event handler } } 

迅速

 override func didMoveToParentViewController(parent: UIViewController?) { if parent == nil { //"Back pressed" } } 

也许这个答案不适合你的解释,但问题的标题。 当你试图知道你什么时候点击了UINavigationBar上的后退button时这很有用。

在这种情况下,您可以使用UINavigationBarDelegate协议并实现以下方法之一:

 - (BOOL)navigationBar:(UINavigationBar *)navigationBar shouldPopItem:(UINavigationItem *)item; - (void)navigationBar:(UINavigationBar *)navigationBar didPopItem:(UINavigationItem *)item; 

didPopItem方法被调用时,这是因为你点击了后退button,或者你使用了[UINavigationBar popNavigationItemAnimated:]方法,并且导航栏确实popup了该项目。

现在,如果你想知道什么动作触发了didPopItem方法,你可以使用一个标志。

使用这种方法,我不需要手动添加带有箭头图像的左侧栏button项目,以使其与iOS后退button类似,并且能够设置我的自定义目标/操作。


我们来看一个例子:

我有一个视图控制器,有一个页面视图控制器和自定义页面指示器视图。 我也使用一个自定义的UINavigationBar来显示一个标题,知道我是在哪个页面上,后退button可以回到上一页。 而且我也可以滑动到页面控制器的上一页/下一页。

 #pragma mark - UIPageViewController Delegate Methods - (void)pageViewController:(UIPageViewController *)pageViewController didFinishAnimating:(BOOL)finished previousViewControllers:(NSArray *)previousViewControllers transitionCompleted:(BOOL)completed { if( completed ) { //... if( currentIndex > lastIndex ) { UINavigationItem *navigationItem = [[UINavigationItem alloc] initWithTitle:@"Some page title"]; [[_someViewController navigationBar] pushNavigationItem:navigationItem animated:YES]; [[_someViewController pageControl] setCurrentPage:currentIndex]; } else { _autoPop = YES; //We pop the item automatically from code. [[_someViewController navigationBar] popNavigationItemAnimated:YES]; [[_someViewController pageControl] setCurrentPage:currentIndex]; } } } 

那么我实现UINavigationBar委托方法:

 #pragma mark - UINavigationBar Delegate Methods - (BOOL)navigationBar:(UINavigationBar *)navigationBar shouldPopItem:(UINavigationItem *)item { if( !_autoPop ) { //Pop by back button tap } else { //Pop from code } _autoPop = NO; return YES; } 

在这种情况下,我使用了shouldPopItem因为pop是animation的,我想立即处理后退button,不要等到转换完成。

didMoveToParentViewController的问题是,它被调用,一旦父视图再次完全可见,所以如果你需要执行一些任务之前,它将无法正常工作。

而且它不适用于驱动的​​animation手势。 使用willMoveToParentViewController效果更好。

Objective-C的

 - (void)willMoveToParentViewController:(UIViewController *)parent{ if (parent == NULL) { // ... } } 

迅速

 override func willMoveToParentViewController(parent: UIViewController?) { if parent == nil { // ... } } 

这是dadachi的 Objective-C版本答案:

Objective-C的

 - (void)didMoveToParentViewController:(UIViewController *)parent{ if (parent == NULL) { NSLog(@"Back Pressed"); } } 

设置UINavigationBar的委托,然后使用:

 - (BOOL)navigationBar:(UINavigationBar *)navigationBar shouldPopItem:(UINavigationItem *)item { //handle the action here } 

设置UINavigationControllerDelegate并实现这个委托func(Swift):

 func navigationController(navigationController: UINavigationController, willShowViewController viewController: UIViewController, animated: Bool) { if viewController is <target class> { //if the only way to get back - back button was pressed } }