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

http://stackoverflow.com/questions/1396582/iphone-navigationcontroller-wait-for-uialertview-response-before-to-quit-the-c


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;
}
}
share | improve this question

80% accept rate
 
feedback

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];
share | improve this answer
 
Sounds logical, but you should probably save the current navigation bar delegate before overwriting it, reset it after you've decided to pop yourself, and maybe even pass through the navigationBar:shouldPopItem:call to the old delegate (if not nil) before showing your alert. –  pix0r  Sep 8 '09 at 22:29
 
The alertview doesn't appear with this code –  Mathieu  Sep 8 '09 at 22:33
 
@Mathieu: Is the method shouldPopItem called? If not, you may have to set the delegate in the viewDidAppear method instead of the init method. pix0r's comment is also valid. I'll update my answer to reflect that. –  Philippe Leybaert  Sep 8 '09 at 22:37
 
The shouldPopItem is not called either if I set the delegate in the viewDidAppear or viewDidLoad or in the init method –  Mathieu  Sep 8 '09 at 22:47
1  
There is a problem with this because you cannot change the delegate for a navigation bar that was "created by a navigation controller and is being managed by that object" (per Apple documentation). –  yabada  Nov 23 '10 at 19:15
feedback

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.

share | improve this answer
 
I have implemented this and can verify that it does work and in my opinion is the cleanest way to accomplish this. –  Jon Steinmetz  Jul 17 '11 at 23:56
feedback

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

UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemSave target:self action:@selector(saveThisDate)]; self.navigationItem.leftBarButtonItem = backButton; [backButton release];

share | improve this answer
 
I tried all the other complicated stuffs from other posts, but this one worked like a charm without the complications. –  gangt  May 21 at 5:19
Was this post useful to you?      

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值