我有一个函数,显示一个UIAlertView与YES/NO按钮,它只用于函数的范围内,所以我不想实现一个委托来捕捉用户反馈。有没有委托处理UIAlertView结果的简单方法?
有没有办法知道哪个按钮用户点击不落实UIAlertViewDelegate,是这样的:
[alert show];
if([alert indexOfClickedButton] == indexOfYes)
{
....
}
或lambda表达式,如动画
我有一个函数,显示一个UIAlertView与YES/NO按钮,它只用于函数的范围内,所以我不想实现一个委托来捕捉用户反馈。有没有委托处理UIAlertView结果的简单方法?
有没有办法知道哪个按钮用户点击不落实UIAlertViewDelegate,是这样的:
[alert show];
if([alert indexOfClickedButton] == indexOfYes)
{
....
}
或lambda表达式,如动画
没有办法完全避免委托,但是您可以沿着这些方向创建一个包装效果:
@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,如果你不使用它改变delegate = nil
至[delegate release]
)
用法是这样的:
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
}];
谢谢,您的解决方案的工作原理。 – jAckOdE 2012-03-13 01:27:41
我在执行'delegate = nil'的行上收到编译器警告:在此块中强烈地捕获委托很可能导致保留周期。这在iOS 5.1 ARC下。 – 2012-05-20 13:25:42
'delegate = nil'是必须的,因为'alertView.delegate'是一个非保留属性,我们需要保持对象为“委托”,直到警报视图为按钮回调完成。这个警告(误报)可以用'#pragma clang diagnostic push'和'#pragma clang diagnostic ignored'-Warc-retain-cycles''忽略,并在该行后面加上'#pragma clang diagnostic pop'。 – AndiDog 2013-09-23 11:24:51
这很容易。假设你有一个警告,这样的事情:
//Alert
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Confirm" message:@"Yes or No?" delegate:self cancelButtonTitle:@"Cancel" otherButtonTitles:@"Yes",@"No", nil];
[alert show];
你将需要添加这个方法:
- (void)alertView:(UIAlertView *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
一种可能实现这个方法的是这样的:
- (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
}
}
你可以做哪些可以隐藏这一点使用自定义视图并显示为避免动作片
UIView *AlertVw=[UIView alloc]initWithFrame:CGRect(x,y,w,h)]];
UIButton *SaveButton=[UIButton alloc]initWithFrame:CGRect(x,y,w,h)]];
[CustomButton setTitle:@"Ok" forState:UIControlStateNormal];
[SaveButton addTarget:self action:@selector(SaveClicked) forControlEvents:UIControlEventTouchUpInside];
UIButton *CancelButton=[UIButton alloc]initWithFrame:CGRect(x,y,w,h)]];
[CustomButton setTitle:@"Cancel" forState:UIControlStateNormal];
[CancelButton addTarget:self action:@selector(CancelClicked) forControlEvents:UIControlEventTouchUpInside];
[AlertVw addSubview:SaveButton];
[AlertVw addSubview:CancelButton];
[self.view addSubview:AlertVw];
-(void)SaveButton
{
//Code to apply on Save clicked
[AlertVw removeFromSuperView]; //Also you can use AlertView.hidden=YES;
}
-(void)CancelButton
{
//Code to apply on cancel clicked
[AlertVw removeFromSuperView]; //Also you can use AlertView.hidden=YES;
}
无需派生类。使用Block,可以很容易地获得用户选择的按钮索引。
typedef void(^AlertViewCallBackBlock)(NSInteger selectedIndex);
@interface ABC()
@property (nonatomic, copy) AlertViewCallBackBlock alertViewBlock;
@end
@implementation
- (void)showAlert {
self.alertViewBlock = ^(NSInteger selectedIndex) {
if (selectedIndex == 1) {
}
};
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Confirm" message:@"Yes or No?" delegate:self cancelButtonTitle:@"Cancel" otherButtonTitles:@"Yes",@"No", nil];
[alert show];
}
- (void)alertView:(UIAlertView *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {
self.alertViewBlock(buttonIndex);
}
@end
我写了一个博客张贴有关如何(以及为何)加挡回调来提醒观点,动作片和动画:
http://blog.innovattic.com/uikitblocks/
如果你只是想这样一个工作实现你可以从GitHub下载源文件:
https://github.com/Innovattic/UIKit-Blocks
用法:
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];
很久以前找到答案,但仍然是很好的作品 – jAckOdE 2014-02-27 02:59:52
谢谢Arkku。这是Swift版本。
https://github.com/exchangegroup/alert-view-with-callback-swift
let alertView = UIAlertView(...)
AlertViewWithCallback().show(alertView) { alertView, buttonIndex in
println("You closed alert by tapping button #\(buttonIndex)")
}
UIAlertView
从iOS版8.0中,建议更好的解决方案将使用UIAlertController
:
let alert = UIAlertController(title: "message", message: "Title", preferredStyle: .Alert)
alert.addAction(UIAlertAction(title: "YES", style: .Default, handler: { (action) -> Void in
// Action for YES
}))
alert.addAction(UIAlertAction(title: "NO", style: .Default, handler: { (action) -> Void in
// Action for NO
}))
self.view.window!.rootViewController!.presentViewController(alert, animated: true, completion: nil)
UIAlertView中没有代表团只有一个,ü创建一个自定义UIAlertView中的方式。 – ios 2012-03-12 05:03:46
这里是一个实现基于块的UIAlertview的网站(以及其他内容):http://blog.mugunthkumar.com/coding/ios-code-block-based-uialertview-and-uiactionsheet/ – lnafziger 2012-03-12 05:18:13
UIAlertView * aletView = [[UIAlertView alloc] initWithTitle:@“Any Title”message:@“Hiii”delegate:self cancelButtonTitle:@“Cancel”otherButtonTitles:nil,nil]; [alert show];如果需要, 不使用任何委托。 – 2012-03-12 09:46:51