Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pause code execution until UIAlertView button is pressed?

Tags:

ios

iphone

One of my methods sends a message to an object (what do you know about that), and expects a BOOL for an answer. However, BOOL answer it is expecting is based on the answer to a UIAlertView created in the receiving object's method. However, the code doesn't pause while waiting for the user to answer the UIAlertView. My problem is: how do I use -alertView:clickedButtonAtIndex in the method's return value?

Here's the code the message runs (in this construction, I was expecting navigateAwayFromTab to change based on the user input in the UIAlertView, but it never gets a chance):

- (BOOL)readyToNavigateAwayFromTab {
    NSLog( @"message received by Medical View");
    navigateAwayFromTab = NO;
    UIAlertView *alert = [[UIAlertView alloc]
           initWithTitle:@"Navigate Away From Tab?"
                 message:@"Navigating away from this tab will save your work."
                delegate:self
       cancelButtonTitle:@"Cancel"
       otherButtonTitles:@"OK", nil
    ];
    [alert show];
    [alert release];
    return navigateAwayFromTab;
}
#define CANCEL 0
#define OK 1
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
    if( buttonIndex == OK ) navigateAwayFromTab = YES;
}

I've been reading up on the modal UIAlertView debate, and I agree with apple's implementation - at lest as the rule. However, in this case I don't see any way of solving the problem by putting code in -alertView:clickedButtonAtIndex because I don't need to run code based on the UIAlertView, I just need to read the response. Any suggestions on how I can reach my gaol? I've tried a while loop after [alert show] already, but then the alert doesn't even show then, and for a number of reasons I can't use -viewWillDisapear.

Edit

For those viewing this question in the modern ios era, this question pertained to ios 2

like image 471
JoBu1324 Avatar asked Dec 08 '22 06:12

JoBu1324


2 Answers

Not only does UIAlertView's show not wait for the user to touch a button, it doesn't even wait for the alert view to fade into view. It returns immediately.

Add a flag to your class. If it's NO, return NO from readyToNavigateAwayFromTab and show your alert. In clickedButtonAtIndex, set the flag so that readyToNavigateAwayFromTab knows to return YES. Still in clickedButtonAtIndex, retry the tab navigation from code.

like image 138
Steven Fisher Avatar answered Dec 28 '22 08:12

Steven Fisher


Solution using NSCondition when triggering from a background thread:

// on background thread
condition = [NSCondition new];
questionAnswered = NO;
// display UIAlertView in a method on main thread with -performSelectorOnMainThread:withObject:waitUntilDone:
[condition lock];
while (! questionAnswered) [condition wait];
questionAnswered = NO;
[condition unlock];
[condition release];

// on main thread in delegate method -alertView:clickedButtonAtIndex:
// (do something with choosen buttonIndex)
questionAnswered = YES;
[condition signal];
[condition unlock]

Raphael

like image 39
Raphael Schaad Avatar answered Dec 28 '22 08:12

Raphael Schaad