-2

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)

SpokaneDude
  • 4,856
  • 13
  • 64
  • 120

1 Answers1

4

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();
    }
}
hsoi
  • 2,764
  • 3
  • 19
  • 20
  • How do I differentiate between several UIAlertViews in the same class? – SpokaneDude Aug 26 '14 at 17:18
  • A couple possible ways. Instead of storing the alloc/init'd UIAlertView in a local variable, you could store it as a class data member, then compare it against the "alertView" argument passed into the delegate method to see if it's the same object. Works, but pretty heavy handed. A lighter way is to utilize the "tag" @property of UIView (of which UIAlertView is one). I'll add an illustration above. – hsoi Aug 26 '14 at 17:20
  • got it... also, there are some 3rd party alertviews(https://github.com/ryanmaxwell/UIAlertView-Blocks ) that use blocks, which looks like it's a lot cleaner. Thank you for your time... I appreciate it. – SpokaneDude Aug 26 '14 at 17:25
  • Yup. Such extensions (I like BlocksKit https://github.com/zwaldowski/BlocksKit) are really useful as well and get around the problem that way too. You're welcome, and happy coding. :-) – hsoi Aug 26 '14 at 17:27