ios 如何捕获后退按钮事件

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1557290/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 16:31:10  来源:igfitidea点击:

How to trap the back button event

iosiphone

提问by Alexi Groove

I have a UITableViewController that launches a UIViewController and I would like to trap whenever the back button is pressed in the child controller, which is the class that derives from 'UIViewController'. I can change the Back Button title but setting the target & action values when setting the backBarButtonItem seems to get ignored. What's a way to receiving some kind of notification that the Back button was tapped?

我有一个启动 UIViewController 的 UITableViewController,我想在子控制器中按下后退按钮时进行捕获,这是从“UIViewController”派生的类。我可以更改后退按钮标题,但在设置 backBarButtonItem 时设置目标和操作值似乎被忽略了。接收“后退”按钮被点击的某种通知的方法是什么?

- (void)showDetailView 
{
    // How I'm creating & showing the detail controller
    MyViewController *controller = [[MyViewController alloc] initWithNibName:@"MyDetailView" bundle:nil];   

    UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithTitle:@"Pages"
                            style:UIBarButtonItemStyleBordered 
                            target:self                                     
                            action:@selector(handleBack:)];

    self.navigationItem.backBarButtonItem = backButton;
    [backButton release];

    [self.navigationController pushViewController:controller animated:animated];
    [controller release];

}   

- (void)handleBack:(id)sender
{
    // not reaching here
    NSLog(@"handleBack event reached");
}

回答by Zoran Simic

You can implement the viewWillDisappearmethod of UIViewController. This gets called when your controller is about to go away (either because another one was pushed onto the navigation controller stack, or because the 'back' button was pressed).

可以实现viewWillDisappearUIViewController的方法。当您的控制器即将消失时(因为另一个控制器被推入导航控制器堆栈,或者因为按下了“后退”按钮),这将被调用。

To determine whether the view is disappearing because of the back button being pressed, you can use a custom flag that you set wherever you push a new controller onto the navigation controller, like shown below

要确定视图是否因按下后退按钮而消失,您可以使用自定义标志,该标志在您将新控制器推到导航控制器上的任何位置设置,如下所示

- (void)viewWillDisappear:(BOOL)animated {
    [super viewWillDisappear:animated];
    if (viewPushed) {
        viewPushed = NO;   // Flag indicates that view disappeared because we pushed another controller onto the navigation controller, we acknowledge it here
    } else {
        // Here, you know that back button was pressed
    }   
}

And wherever you push a new view controller, you would have to remember to also set that flag...

无论你推送一个新的视图控制器,你都必须记住还要设置那个标志......

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    ...
    viewPushed = YES;
    [self.navigationController pushViewController:myNewController animated:YES];
    ...
}

回答by Andrew

It has been a while since this was asked, but I just tried to do this myself. I used a solution similar to Zoran's, however instead of using a flag I did this:

自从被问到这个问题已经有一段时间了,但我只是尝试自己做。我使用了类似于 Zoran 的解决方案,但是我没有使用标志,而是这样做了:

- (void)viewWillDisappear: (BOOL)animated
{
    [super viewWillDisappear: animated];
    if (![[self.navigationController viewControllers] containsObject: self])
    {
        // the view has been removed from the navigation stack, back is probably the cause
        // this will be slow with a large stack however.
    }
}

I think it bypasses the issues with flags and IMO is cleaner, however not as efficient (if there are lots of items on the navigation controller).

我认为它绕过了标志的问题,IMO 更干净,但效率不高(如果导航控制器上有很多项目)。

回答by Blank

In my opinion the best solution.

在我看来最好的解决方案。

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

But it only works with iOS5+

但它只适用于 iOS5+

回答by m8labs

I use this code:

我使用这个代码:

- (void) viewWillDisappear:(BOOL)animated {

   if ([self.navigationController.viewControllers indexOfObject:self] == NSNotFound)
   {
      // your view controller already out of the stack, it meens user pressed Back button
   }
}

But this is not actual when user presses tab bar button and pops to root view controller at one step. For this situation use this:

但是当用户按下标签栏按钮并一步弹出到根视图控制器时,这不是实际的。对于这种情况,请使用:

   [[NSNotificationCenter defaultCenter] addObserver:self
                                            selector:@selector(viewControllerChange:)
                                                name:@"UINavigationControllerWillShowViewControllerNotification"
                                              object:self.navigationController];


- (void) viewControllerChange:(NSNotification*)notification {

   NSDictionary* userInfo = [notification userInfo];

   if ([[userInfo objectForKey:@"UINavigationControllerNextVisibleViewController"] isKindOfClass:[<YourRootControllerClass> class]])
   { 
      // do your staff here
   }
}

Don't forget then:

别忘了:

   [[NSNotificationCenter defaultCenter] removeObserver:self
                                                   name:@"UINavigationControllerWillShowViewControllerNotification"
                                                 object:self.navigationController];

回答by coneybeare

You can make your own button and place it as the leftBarButtonItem. Then have it call your method where you can do whatever, and call [self.navigationController popViewController...yourself

您可以制作自己的按钮并将其放置为leftBarButtonItem. 然后让它调用你的方法,你可以做任何事情,然后调用[self.navigationController popViewController...你自己

回答by PRASANTH P.C

{
    UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithTitle:@"back"
                                                                   style:UIBarButtonItemStyleBordered 
                                                                  target:self                                                                             
                                                                  action:@selector(handleBack:)];
    self.navigationItem.leftBarButtonItem = backButton;
    [backButton release];
    [self filldata];
    [super viewDidLoad];
}

just replace backBarButtonItemwith leftBarButtonItem

只需替换backBarButtonItemleftBarButtonItem

回答by Udo Günther

Simply use viewDidDisappearinstead. It will be perfectly called in any scenario.

简单地使用viewDidDisappear。在任何情况下都会完美地调用它。

We are basing your lifecycle management on viewDidAppear and viewDidDisappear. If you know Android: the both are comparable to onResume and onPause methods. But there is a difference when it comes to locking the screen or pressing the homebutton on iOS.

我们将您的生命周期管理基于 viewDidAppear 和 viewDidDisappear。如果您了解 Android:两者都可以与 onResume 和 onPause 方法相媲美。但是在 iOS 上锁定屏幕或按下 Home 键是有区别的。