2009-10-12 2 views
16

У меня есть 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"); 
} 
+1

Для людей, которые ищут эффективное решение iOS 5+: http: // stackoverflow.com/a/13370744/1072846 – Eric

ответ

1

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

+1

«leftBarButtonItem» не будет показывать тот же стиль кнопки с боковым треугольником. Вместо этого я думаю, что кнопка будет квадратной. Есть ли способ сделать его похожим на типичную подкладку, а также на захват события? –

+0

Вы можете создать собственное изображение левой стрелки, если знаете ширину текста на кнопке - или вы можете создать его программно, подражая тому, что делает Apple. – coneybeare

18

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

Как вы знаете, что представление не исчезло, потому что какая-то другая кнопка вызывала дочерний вид? Я хочу знать, только когда нажата кнопка «Назад». –

+0

В таких случаях я установил флаг в файле didSelectRowAtIndexPath: (где вы обычно нажимаете новый контроллер на контроллер навигации). viewWillDisappear может затем проверить этот флаг и вывести, была ли нажата кнопка возврата или нет. –

+0

Это все еще не касается проблемы, о которой указал Джастин; С вашим флагом вы узнаете, как возникла точка зрения, но это не значит, что это единственный способ ее исчезновения. – kbanman

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

Я думаю, что он обходит проблемы с флагами и ИМО чище, но не так эффективно (если есть много пунктов на навигационный контроллер).

+6

Возможно, вы можете использовать '[self.navigationController.viewControllers indexOfObjectIdenticalTo: self]! = NSNotFound' вместо' containsObject', который будет сравнивать только адрес указателя. –

+0

Проверено: Работает. –

+1

Если ваш контроллер находится в другом контейнере, вам придется сравнивать: «indexOfObjectIdenticalTo: self.parentViewController», кроме этого, работает. – marmor

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

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

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

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

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

+0

Это лучшее решение, которое я думаю, поскольку оно более самодостаточно. – canhazbits

+0

где написать это – NaXir

-2

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

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