Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

iphone navigationController : wait for uialertview response before to quit the current view

I have a view with a back button managed with a navigation controller and I want to check if a file has been saved when the user click on the back button. If the file has been saved you go back in the previous view, else a uialertview ask you if you want to save the file or not.

So I did that but the view disapear and the alertview appear after.

-(void)viewWillDisappear:(BOOL)animated {
if(!self.fileSaved){
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"" message:@"Save the file?"  delegate:self cancelButtonTitle:@"No" otherButtonTitles:@"Yes",nil];
    [alert show];
    [alert release];
}
}

- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex
{
switch (buttonIndex) {
    case 0:
        NSLog(@"NO");
        break;
    case 1:
        NSLog(@"yes");
        break;
    default:
        break;
}
}
like image 516
Mathieu Avatar asked Sep 08 '09 22:09

Mathieu


3 Answers

When viewWillDisappear is called, it's already too late. You should intercept the back button earlier on. I have never done it, but my suggestion is to set the delegate on the navigationBar property in your viewDidAppear method:

// save the previous delegate (create an ivar for that)
prevNavigationBarDelegate = self.navigationController.navigationBar.delegate;

self.navigationController.navigationBar.delegate = self;

Don't forget to set it back in viewWillDisappear:

self.navigationController.navigationBar.delegate = prevNavigationBarDelegate;

Then intercept the shouldPopItem method:

- (BOOL)navigationBar:(UINavigationBar *)navigationBar shouldPopItem:(UINavigationItem *)item {
     if(!self.fileSaved) {
         UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"" message:@"Save the file?"  delegate:self cancelButtonTitle:@"No" otherButtonTitles:@"Yes",nil];
         [alert show];
         [alert release];

         return NO;
     }

   if ([prevNavigationBarDelegate respondsToSelector:@selector(navigationBar:shouldPopItem:)]) 
      return [prevNavigationBarDelegate navigationBar:navigationBar shouldPopItem:item];

   return YES; 
}

And in the YES handler for the dialog, manually pop the controller:

[self.navigationController popViewController:YES];
like image 131
Philippe Leybaert Avatar answered Nov 15 '22 00:11

Philippe Leybaert


You must subclass UINavigationController for this to work. Then override - (BOOL)navigationBar:(UINavigationBar *)navigationBar shouldPopItem:(UINavigationItem *)item . You should set up a custom Delegate protocol that your view controllers adopt and, if you allow it to pop, call your [super navigationBar shouldPopItem:], else, return NO to the above method.

like image 24
Rafael Nobre Avatar answered Nov 14 '22 22:11

Rafael Nobre


Wouldn't it be easier just to add a left button item as in the following:

UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemSave target:self action:@selector(saveThisDate)];
self.navigationItem.leftBarButtonItem = backButton;
[backButton release];
like image 31
John Avatar answered Nov 14 '22 23:11

John