Как перехватить событие «Назад» - PullRequest
17 голосов
/ 13 октября 2009

У меня есть 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 ]

19 голосов
/ 13 октября 2009

Вы можете реализовать метод viewWillDisappear UIViewController. Это вызывается, когда ваш контроллер собирается уйти (либо потому, что другой был помещен в стек контроллера навигации, либо потому, что была нажата кнопка «назад»).

Чтобы определить, исчезает ли вид из-за нажатия кнопки «Назад», вы можете использовать пользовательский флаг, который вы устанавливаете всякий раз, когда нажимаете новый контроллер на контроллер навигации, как показано ниже

- (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];
    ...
}
17 голосов
/ 27 апреля 2012

Прошло много времени с тех пор, как об этом спросили, но я просто попытался сделать это сам. Я использовал решение, похожее на решение Зорана, однако вместо флага я сделал это:

- (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 чище, но не так эффективно (если на контроллере навигации много элементов).

13 голосов
/ 30 мая 2013

На мой взгляд лучшее решение.

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

Но работает только с iOS5 +

8 голосов
/ 09 июля 2012

Я использую этот код:

- (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];
1 голос
/ 13 октября 2009

Вы можете сделать свою собственную кнопку и разместить ее как leftBarButtonItem. Затем пусть он вызывает ваш метод, где вы можете делать все что угодно, и вызываете [self.navigationController popViewController... себя

0 голосов
/ 11 мая 2015

Просто используйте viewDidDisappear вместо. Это будет прекрасно называться в любом сценарии.

Мы основываем управление вашим жизненным циклом на viewDidAppear и viewDidDisappear. Если вы знаете Android: оба сравнимы с методами onResume и onPause. Но есть разница, когда дело доходит до блокировки экрана или нажатия кнопки Home на iOS.

0 голосов
/ 21 мая 2012
{
    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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...