如何捕获后退按钮事件

时间:2009-10-12 22:29:11

标签: ios iphone

我有一个UITableViewController,它启动一个UIViewController,我想在子控制器中按下后退按钮时陷阱,这是从'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");
}

7 个答案:

答案 0 :(得分:19)

您可以实现UIViewController的viewWillDisappear方法。当你的控制器即将离开时,这会被调用(因为另一个被推到导航控制器堆栈上,或者因为按下了'后退'按钮)。

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

- (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
    }   
}

无论你在哪里推新的视图控制器,你都必须记住也设置那个标志......

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

答案 1 :(得分:17)

自从被问到这个问题已经有一段时间了,但我只是试着自己这样做。我使用了类似于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.
    }
}

我认为它绕过了旗帜的问题,IMO更清晰,但效率不高(如果导航控制器上有很多物品)。

答案 2 :(得分:13)

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

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

但它只适用于iOS5 +

答案 3 :(得分:8)

我使用此代码:

- (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
   }
}

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

   [[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
   }
}

不要忘了:

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

答案 4 :(得分:1)

您可以创建自己的按钮并将其设置为leftBarButtonItem。然后让它调用您可以执行任何操作的方法,并自己致电[self.navigationController popViewController...

答案 5 :(得分:0)

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

只需将backBarButtonItem替换为leftBarButtonItem

答案 6 :(得分:-2)

只需使用viewDidDisappear即可。在任何情况下都会完美地调用它。

我们将您的生命周期管理基于viewDidAppear和viewDidDisappear。如果您了解Android:两者都与onResume和onPause方法相当。但是在锁定屏幕或按下iOS上的主页按钮时会有所不同。