尝试在iOS中处理"后退"导航按钮操作

App*_*Dev 71 selector uinavigationbar uinavigationcontroller ios

我需要检测用户何时点击导航栏上的"后退"按钮,以便在发生这种情况时执行某些操作.我正在尝试手动将动作设置为这样的按钮,这样:

[self.navigationItem.backBarButtonItem setAction:@selector(performBackNavigation:)];

- (void)performBackNavigation:(id)sender
{
   // Do operations

   [self.navigationController popViewControllerAnimated:NO];
}
Run Code Online (Sandbox Code Playgroud)

我首先将该代码放在视图控制器本身中,但我发现它self.navigationItem.backBarButtonItem似乎是nil,所以我将相同的代码移动到父视图控制器,后者将前者推送到导航堆栈.但我无法让它发挥作用.我已经阅读了一些关于这个问题的帖子,其中一些人说需要在父视图控制器上设置选择器,但对我来说它无论如何都不起作用......我怎么可能做错了?

谢谢

Kum*_* KL 129

尝试使用此VIewWillDisappear方法使用方法检测NavigationItem后退按钮的按下:

-(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];
}
Run Code Online (Sandbox Code Playgroud)

或者还有另一种获取导航BAck按钮的方法.

为后退按钮的UINavigationItem创建自定义按钮.

对于Ex:

在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];
}
Run Code Online (Sandbox Code Playgroud)

斯威夫特:

override func willMoveToParentViewController(parent: UIViewController?) 
{
    if parent == nil 
    {
        // Back btn Event handler
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 我认为你在viewWillDisappear中不需要[self.navigationController popViewControllerAnimated:NO]. (3认同)
  • 我认为这个方法不再适用于iOS 8,因为self.navigationController.viewControllers只包含一个元素,== self (2认同)

dad*_*chi 41

迅速

override func didMoveToParentViewController(parent: UIViewController?) {
    if parent == nil {
        //"Back pressed"
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 这个解决方案唯一的问题是,如果你滑动回去,改变主意,这将被触发. (5认同)

Fir*_*ula 16

也许这个答案不适合你的解释,但问题标题.当你试图知道何时点击后退按钮时它很有用UINavigationBar.

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

- (BOOL)navigationBar:(UINavigationBar *)navigationBar shouldPopItem:(UINavigationItem *)item;
- (void)navigationBar:(UINavigationBar *)navigationBar didPopItem:(UINavigationItem *)item;
Run Code Online (Sandbox Code Playgroud)

didPopItem调用方法时,这是因为您点击了后退按钮或者您使用了[UINavigationBar popNavigationItemAnimated:]方法,导航栏确实弹出了该项目.

现在,如果您想知道触发该didPopItem方法的操作,您可以使用标志.

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


我们来看一个例子:

我有一个视图控制器,它有一个页面视图控制器和一个自定义页面指示器视图.我也使用自定义UINavigationBar来显示标题,以便知道我在哪个页面以及返回上一页的后退按钮.我也可以在页面控制器上滑动到上一页/下一页.

#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];
        }
    }

}
Run Code Online (Sandbox Code Playgroud)

那么我实现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;
}
Run Code Online (Sandbox Code Playgroud)

在这种情况下我使用,shouldPopItem因为pop是动画的,我想立即处理后退按钮,而不是等到转换完成.


Nic*_*ico 12

问题didMoveToParentViewController是,一旦父视图再次完全可见就会调用它,所以如果你需要在此之前执行某些任务,它将无法工作.

它不适用于驱动动画手势.使用willMoveToParentViewController效果更好.

Objective-C的

- (void)willMoveToParentViewController:(UIViewController *)parent{
    if (parent == NULL) {
        // ...
    }
}
Run Code Online (Sandbox Code Playgroud)

迅速

override func willMoveToParentViewController(parent: UIViewController?) {
    if parent == nil {
        // ...  
    }
}
Run Code Online (Sandbox Code Playgroud)


Ash*_*kad 6

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

Objective-C的

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