Подтвердить что ты не робот

Как заблокировать событие кнопки "Назад"

У меня есть UITableViewController, который запускает UIViewController, и я хотел бы уловить всякий раз, когда в дочернем контроллере нажата кнопка "Назад" , которая является классом, который происходит из "UIViewController". Я могу изменить заголовок кнопки "Назад" , но при установке значения target и action при установке 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");
}
4b9b3361

Ответ 1

Вы можете реализовать метод 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];
    ...
}

Ответ 2

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

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

Ответ 3

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

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

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

Ответ 4

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

- (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];

Ответ 5

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

Ответ 6

{
    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

Ответ 7

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

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