Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

is there easy way to handle UIAlertView result without delegation?

I have a function that shows a UIAlertView with YES/NO buttons, and it is used only inside the function's scope so I dont want to implement a delegation to catch the user feedback.

Is there any way to know what button users clicked without implement UIAlertViewDelegate, something like:

[alert show];
if([alert indexOfClickedButton] == indexOfYes)
{
....
}

Or lambda expression as in Animation

like image 379
jAckOdE Avatar asked Mar 12 '12 04:03

jAckOdE


3 Answers

There is no way to avoid delegation completely, but you could create a wrapper to that effect along these lines:

@interface MyAlertViewDelegate : NSObject<UIAlertViewDelegate>

typedef void (^AlertViewCompletionBlock)(NSInteger buttonIndex);
@property (strong,nonatomic) AlertViewCompletionBlock callback;

+ (void)showAlertView:(UIAlertView *)alertView withCallback:(AlertViewCompletionBlock)callback;

@end


@implementation MyAlertViewDelegate
@synthesize callback;

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

+ (void)showAlertView:(UIAlertView *)alertView
         withCallback:(AlertViewCompletionBlock)callback {
    __block MyAlertViewDelegate *delegate = [[MyAlertViewDelegate alloc] init];
    alertView.delegate = delegate;
    delegate.callback = ^(NSInteger buttonIndex) {
        callback(buttonIndex);
        alertView.delegate = nil;
        delegate = nil;
    };
    [alertView show];
}

@end

(ARC is assumed, if you are not using it change delegate = nil to [delegate release].)

Usage would be something like:

UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Confirm" message:@"Yes or No?" delegate:nil cancelButtonTitle:@"Cancel" otherButtonTitles:@"Yes",@"No", nil];
[MyAlertViewDelegate showAlertView:alert withCallback:^(NSInteger buttonIndex) {
    // code to take action depending on the value of buttonIndex
}];
like image 90
Arkku Avatar answered Sep 30 '22 08:09

Arkku


I have written a blog post about how to (and why) add block callbacks to alert views, action sheets and animations:

http://blog.innovattic.com/uikitblocks/

If you just want a working implementation of this you can download the sources files from GitHub:

https://github.com/Innovattic/UIKit-Blocks

Usage:

UIAlertView* alert = [[UIAlertView alloc] initWithTitle:@"My easy alert"  
                                                message:@"Would you like to perform some kind of action?"
                                      cancelButtonTitle:@"No"
                                      otherButtonTitles:@"Yes", nil];
[alert setHandler:^(UIAlertView* alert, NSInteger buttonIndex) {
    NSLog(@"Perform some kind of action");
} forButtonAtIndex:[alert firstOtherButtonIndex]];
[alert show];
like image 35
Desmond Avatar answered Sep 27 '22 08:09

Desmond


It's very easy. Say you have an alert, something like this:

//Alert
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Confirm" message:@"Yes or No?" delegate:self cancelButtonTitle:@"Cancel" otherButtonTitles:@"Yes",@"No", nil];
[alert show];

You're going to need to add this method:

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

A possible implementation of this method would look like this:

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

//Checks For Approval
    if (buttonIndex == 1) {
        //do something because they selected button one, yes
    } else {
        //do nothing because they selected no
    }
}
like image 20
JTApps Avatar answered Sep 29 '22 08:09

JTApps