0

I am calling a UIAlertView within it's own delegate and it is failing. The code is simple:

@interface ViewController () <UIAlertViewDelegate>
@property (nonatomic, strong) UIAlertView *alertView;
@end

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    self.alertView = [[UIAlertView alloc] initWithTitle:@"Howdy"
                                                message:@"Here's the alert"
                                               delegate:self
                                      cancelButtonTitle:@"Cancel"
                                      otherButtonTitles:@"OK", nil];
    [self.alertView show]; // this shows the 
}


- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex
{
    if (buttonIndex == 1) {
        [self.alertView show]; // this does not show the alert again!
    }
}

@end

However, when I remove:

[self.alertView show] 

and replace it with:

[self.alertView performSelector:@selector(show) withObject:nil afterDelay:0.01]

it works.

This seems to indicate that the original UIAlertVIew is not completely dismissed even though I am inside the delegate method alertView:didDismissWithButtonIndex:.

While this is working, it does not seem right. Can anyone tell me what I am doing wrong?

nurider
  • 1,555
  • 1
  • 18
  • 21
  • Probably 2 animations being launched simultaneously. Dismiss and Present. This would result in a fail for both of then. – Kujey May 22 '14 at 22:16

1 Answers1

2

You are probably right, but I don't see why would you show the same alert again. Since you usually do not require to keep a reference to an alert, you could just write a method like:

- (void)showAlert {
   UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Howdy"
                                                   message:@"Here's the alert"
                                                  delegate:self
                                         cancelButtonTitle:@"Cancel"
                                         otherButtonTitles:@"OK", nil];
    [alert show];
}

It would also be better if you would call this from viewDidAppear instead of viewDidLoad.

Levi
  • 7,313
  • 2
  • 32
  • 44
  • I need to collect text in the UIAlertView and if the user does not enter the text I need to ask for it again. While I would like to show the same alert without having to re-create it, I may have to do what you suggest. Yours is probably the best answer but I'll see what others suggested in the next few hours. Thx! – nurider May 22 '14 at 22:44
  • Then a better approach might be to prevent the dismissal in the first place, see [here](http://stackoverflow.com/questions/2051402/is-it-possible-to-not-dismiss-a-uialertview). In either case it seems like some user feedback should be provided so they know why the alert keeps popping up. – David Berry May 22 '14 at 22:48
  • Even better yet, just disable the buttons when there's no text yet entered. See [here](http://stackoverflow.com/a/1950969/3203487) – David Berry May 22 '14 at 22:52
  • You can still get the text field in the delegate methods, without keeping a reference to the alert. @David's solution to disable the button seems good too. You should make sure however, that you really need an alert. They are usually used to indicate that something went wrong in the app, or use it as a confirmation dialog when you are about to delete some very important data and an action sheet won't do. But you should not use it if you only want to request e.g. a password from the user to log in, you could use for this a normal view controller. – Levi May 23 '14 at 05:58
  • I solved it by using both of your suggestions. I disable the button until the information is correctly entered (great suggestion) and I no longer show the same alert more than once. Thanks very much! – nurider May 23 '14 at 14:10