有没有委托处理UIAlertView结果的简单方法?

时间:2012-03-12 04:49:51

标签: iphone ios xcode cocoa-touch

我有一个显示带有YES / NO按钮的UIAlertView的函数,它只在函数范围内使用,因此我不想实现委托以捕获用户反馈。

有没有办法知道用户点击的按钮没有实现UIAlertViewDelegate,如:

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

或者动画

中的lambda表达式

7 个答案:

答案 0 :(得分:23)

没有办法完全避免委托,但你可以在这些方面创建一个包装器:

@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
}];

答案 1 :(得分:3)

我写了一篇关于如何(以及为什么)添加块回调以提醒视图,操作表和动画的博客文章:

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];

答案 2 :(得分:1)

这很容易。假设您有警报,如下所示:

//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
    }
}

答案 3 :(得分:0)

您可以使用自定义视图执行此操作,该视图可以隐藏并显示以避免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;

 }

答案 4 :(得分:0)

无需派生课程。使用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

答案 5 :(得分:0)

感谢 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)")
}

答案 6 :(得分:0)

从iOS 8.0弃用

UIAlertView,更好的解决方案是使用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)