xcode 有没有简单的方法可以在没有委托的情况下处理 UIAlertView 结果?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/9661900/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
is there easy way to handle UIAlertView result without delegation?
提问by HymanOdE
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.
我有一个显示带有 YES/NO 按钮的 UIAlertView 的函数,它只在函数的范围内使用,所以我不想实现一个委托来捕捉用户反馈。
Is there any way to know what button users clicked without implement UIAlertViewDelegate, something like:
有没有办法知道用户在不实现 UIAlertViewDelegate 的情况下单击了什么按钮,例如:
[alert show];
if([alert indexOfClickedButton] == indexOfYes)
{
....
}
Or lambda expression as in Animation
或动画中的 lambda 表达式
回答by Arkku
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]
.)
(假设为 ARC,如果您不使用它,请更改delegate = nil
为[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
}];
回答by Desmond
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/
http://blog.innovattic.com/uikitblocks/
If you just want a working implementation of this you can download the sources files from GitHub:
如果你只是想要一个有效的实现,你可以从 GitHub 下载源文件:
https://github.com/Innovattic/UIKit-Blocks
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];
回答by JTApps
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
}
}
回答by Sanket Pandya
You can do this using custom view which can be hidden and shown to avoid ActionSheets
您可以使用自定义视图来执行此操作,该视图可以隐藏和显示以避免 ActionSheets
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;
}
回答by bademi
No need to derive the class. With Block, it is easy to get user selected button index.
不需要派生类。使用 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
回答by Evgenii
Thanks Arkku. Here is the Swift version.
谢谢阿库。这是 Swift 版本。
https://github.com/exchangegroup/alert-view-with-callback-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)")
}
回答by idanuda
UIAlertView
is deprecated from iOS 8.0, a better solution will be using UIAlertController
:
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)