20

Can someone explain how the delegate to a UIAlertView works? Is it automatically called or do I have to call it? Eg:

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

Bartłomiej Semańczyk
  • 59,234
  • 49
  • 233
  • 358
Joe
  • 1,326
  • 7
  • 34
  • 52
  • I wrote a generic class for replacing UIAlertView delegation with block callbacks. You can check it out [here](http://stavash.wordpress.com/2013/01/31/quick-tip-uialertview-with-a-block-callback/). – Stavash Jan 31 '13 at 21:53

4 Answers4

32

Let's say you showed an alert where the delegate was "self"

- (void)showAlert {
        UIAlertView *myAlert = [[UIAlertView alloc] initWithTitle:@"My Alert" 
                                                       message:@"Do you want to continue?"
                     delegate:self
                  cancelButtonTitle:nil
                  otherButtonTitles:@"No", @"Yes", nil];
        [myAlert show];
        [myAlert release];
}

In order for the following to work in your .m file:

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

Your .h file will need to reference the UIAlertViewDelegate in the implementation statement like so:

@interface myViewController : UIViewController <UIAlertViewDelegate> {
}

This is what allows your .m file to respond to UIAlertViewDelegate method calls.

dredful
  • 4,378
  • 2
  • 35
  • 54
  • 2
    Having the delegate listed in the header isn't necessary, but is good practice – braden Mar 06 '14 at 14:51
  • Why this isn't said in the documentation!? https://developer.apple.com/library/ios/documentation/uikit/reference/UIAlertView_Class/UIAlertView/UIAlertView.html#//apple_ref/occ/instm/UIAlertView/initWithTitle:message:delegate:cancelButtonTitle:otherButtonTitles: – Paweł Brewczynski Apr 01 '14 at 10:13
11

So long as you're correctly setting the delegate property of the UIAlertView and implementing the protocol, it will be automatically called when a user clicks on a button in your alert.

Take a look at the projects listed under "Related sample code" at http://developer.apple.com/library/ios/#documentation/UIKit/Reference/UIAlertViewDelegate_Protocol/UIAlertViewDelegate/UIAlertViewDelegate.html to see it in action.

Kris Markel
  • 12,142
  • 3
  • 43
  • 40
  • looks like i wasn't calling delegate:self in the init, thanks for te quick response – Joe Sep 29 '10 at 23:54
10

Here is a wrapper for the delegate so that you can use blocks instead. The flow of execution will be the same but the flow of the code will be easier to follow. So, usage:

[YUYesNoListener yesNoWithTitle:@"My Title" message:@"My Message" yesBlock:^
{
    NSLog(@"YES PRESSED!");
}
noBlock:^
{
    NSLog(@"NO PRESSED!");
}];

...and here is the helper class:

typedef void(^EmptyBlockType)();

@interface YUYesNoListener : NSObject <UIAlertViewDelegate>

@property (nonatomic, retain) EmptyBlockType yesBlock;
@property (nonatomic, retain) EmptyBlockType noBlock;

+ (void) yesNoWithTitle:(NSString*)title message:(NSString*)message yesBlock:(EmptyBlockType)yesBlock noBlock:(EmptyBlockType)noBlock;

@end

@implementation YUYesNoListener

@synthesize yesBlock = _yesBlock;
@synthesize noBlock = _noBlock;

- (id) initWithYesBlock:(EmptyBlockType)yesBlock noBlock:(EmptyBlockType)noBlock
{
    self = [super init];
    if (self)
    {
        self.yesBlock = [[yesBlock copy] autorelease];
        self.noBlock = [[noBlock copy] autorelease];
    }
    return self;
}

- (void) alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
    if (buttonIndex == 0 && self.noBlock)
        self.noBlock();
    else if (buttonIndex == 1 && self.yesBlock)
        self.yesBlock();

    [_yesBlock release];
    [_noBlock release];
    [alertView release];
    [self release];
}

- (void) alertViewCancel:(UIAlertView *)alertView
{
    if (self.noBlock)
        self.noBlock();
    [_yesBlock release];
    [_noBlock release];
    [alertView release];
    [self release];
}

+ (void) yesNoWithTitle:(NSString*)title message:(NSString*)message yesBlock:(EmptyBlockType)yesBlock noBlock:(EmptyBlockType)noBlock
{
    YUYesNoListener* yesNoListener = [[YUYesNoListener alloc] initWithYesBlock:yesBlock noBlock:noBlock];
    [[[UIAlertView alloc] initWithTitle:title message:message delegate:yesNoListener cancelButtonTitle:@"No" otherButtonTitles:@"Yes", nil] show];
}

@end
Ricky Helgesson
  • 3,596
  • 2
  • 21
  • 23
2

The alertView:clickedButtonAtIndex: method of the delegate is automatically called by UIAlertView. The init method for UIAlertView takes a delegate as one of the parameters. Just make sure to pass in an object that responds to alertView:clickedButtonAtIndex:.

James Huddleston
  • 8,410
  • 5
  • 34
  • 39