Search code examples
objective-cios7uialertviewuialertviewdelegate

Why is the UIAlertView not blocking until user responds by tapping a button?


In my iOS 7 app, I need to verify the user wants to deleta a selected record from Cord Data. I have the UIAlertViewDelegate defined in the .h file. This is the code to display the alert:

UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Warning"
                                                message:@"Are you sure you want to delete this record?"
                                               delegate:self
                                      cancelButtonTitle:@"Cancel"
                                      otherButtonTitles:@"Delete", nil];
[alert show];

if(alertButtonTapped == 0)
    return;

//  remainder of code to delete record follows (was omitted)

This is the code to check which button was tapped:

- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex  {  

alertButtonTapped = [NSNumber numberWithInteger:buttonIndex];
return;
}

The problem is the alert is displayed and then immediately falls through the remainder of the code in that method. I have never seen this before; usually it blocks until the user has responded by tapping one of the buttons (at least I thought it did). What do I need to do to make this alert block until the user responds? (I was looking at UIAlertView blocks, but not sure that would do the job since it appears to use a different thread)


Solution

  • This is how UIAlertView works -- it doesn't block, thus why it has the UIAlertViewDelegate methods for actually implementing a response.

    If the "remainder of code" is what should happen after they tap a button (e.g. the "Delete" button), then move all of that code into the delegate method, like:

    - (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex  {  
        if (buttonIndex != alertView.cancelButtonIndex) {
            // code to delete record
        }
    }
    

    EDIT - adding example to answer a comment

    So if you have multiple UIAlertViews in the same class, you could differentiate between them using the tag attribute of UIView (UIAlertView is-a UIView). So it could be something like this:

    const NSInteger kDeleteAlertTag = 100;  // declared at the top of your .m file, perhaps.
    
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Warning"
                                                    message:@"Are you sure you want to delete this record?"
                                                   delegate:self
                                          cancelButtonTitle:@"Cancel"
                                          otherButtonTitles:@"Delete", nil];
    alert.tag = kDeleteAlertTag;
    [alert show];
    

    Then your delegate response might look like this:

    - (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex  {  
        if (alertView.tag == kDeleteAlertTag) {
            if (buttonIndex != alertView.cancelButtonIndex) {
                // code to delete record
            }
        }
        else if (alertView.tag = kDoSomethingElseAlertTag) {
            DoSomethingElse();
        }
    }