is there easy way to handle UIAlertView result without delegation?
Solution 1
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
}];
Solution 2
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];
Solution 3
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
}
}
Comments
-
jAckOdE almost 2 years
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
-
Arkku about 12 yearsBut he specifically asked how to do it without delegation…
-
jAckOdE about 12 yearsThank! And yes, it will save me some line of codes, but i still have to write some code outside of the function's scope and, probably, save a reference of the alertview, that is what I dont want. I'm looking for a block-based solution, and if there is no simple way to do that, I think your solution would be the best.
-
Jtaylorapps about 12 yearsGlad I was able to help out some!
-
Peter Warbo almost 12 yearsI'm getting a compiler warning on the line where you do
delegate = nil
saying : Capturing delegate strongly in this block is likely to lead to a retain cycle. This under iOS 5.1 ARC. -
AndiDog over 10 years
delegate = nil
is necessary becausealertView.delegate
is a non-retaining property and we need to keep the object "delegate" until the alert view is button callback is finished. The warning (a false positive) can be ignored with#pragma clang diagnostic push
and#pragma clang diagnostic ignored "-Warc-retain-cycles"
before, and#pragma clang diagnostic pop
after that line. -
Ferran Maylinch about 10 yearsGreat, thank! You can just pass
delegate:nil
when creating the alert. -
Arkku almost 9 years2015 update:
UIAlertView
is deprecated and its replacement,UIAlertController
, allows adding actions withUIAlertAction
, which takes a block as action handler. -
rakeshNS over 8 years@jAckOdE if you do not want to keep a reference for alert view object, you can use tags for alert view. example, alert = 101; and in - (void)alertView:(UIAlertView *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex, you can check , if alert.tag == 101 {}....