如何在UIAlertView中为按钮编写事件处理程序?

时间:2011-09-13 05:11:05

标签: objective-c ios uialertview

假设我在obj c

中有如下的警报视图
UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"title" message:@"szMsg" delegate:nil cancelButtonTitle:@"Ok" otherButtonTitles:@"download"];
        [alert show];
        [alert release];

现在我们在警报视图上有2个按钮(Ok& Download),如何为下载一个编写事件处理程序?

8 个答案:

答案 0 :(得分:45)

首先,您需要将UIAlertViewDelegate添加到头文件中,如下所示:

标题文件(.h)

@interface YourViewController : UIViewController<UIAlertViewDelegate> 

实施档案(.m)

UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"title" message:@"szMsg" delegate:self cancelButtonTitle:@"Ok" otherButtonTitles:@"download"];
        [alert show];
        [alert release];

- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
    if (buttonIndex == 0)
    {
        //Code for OK button
    }
    if (buttonIndex == 1)
    {
        //Code for download button
    }
}

答案 1 :(得分:5)

现在大多数iOS设备都拥有使用块支持的极端版本​​,使用笨拙的回调API来处理按钮按钮是不合时宜的。块是可行的方法,例如参见Lambda Alert classes on GitHub

CCAlertView *alert = [[CCAlertView alloc]
    initWithTitle:@"Test Alert"
    message:@"See if the thing works."];
[alert addButtonWithTitle:@"Foo" block:^{ NSLog(@"Foo"); }];
[alert addButtonWithTitle:@"Bar" block:^{ NSLog(@"Bar"); }];
[alert addButtonWithTitle:@"Cancel" block:NULL];
[alert show];

答案 2 :(得分:2)

宣布您的UIAlertView已知。

UIAlertView *alertLogout=[[UIAlertView alloc]initWithTitle:@"Title" message:@"Stop Application?" delegate:self cancelButtonTitle:@"No" otherButtonTitles:@"Yes",nil]; 

[alertLogout show]; 

[alertLogout release];

将委托设置为self并实现此方法。

-(void)alertView:(UIAlertView *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {
    if(actionSheet== alertLogout) {//alertLogout
        if (buttonIndex == 0){

        }else if(buttonIndex==1){

        }
    }else if (actionSheet==alertComment) {//alertComment
        if (buttonIndex==0) {

        }
    }
}

答案 3 :(得分:2)

Stack和Guillermo Ortega的答案很可能就是你会用到几个UIAlertView而不是10个。我习惯使用BlocksKit,这与灵魂建议的Lambda东西相同。这也是一个不错的选择,但如果你有太多的嵌套块,你将开始看到它的缺点(除了你将依赖于另一个库的事实)。

处理几个东西的常用方法是拥有一个处理程序对象。 ( @interface MyAlertViewDelegate : NSObject <UIAlertViewDelegate> @end)使该对象成为警报视图的委托,并确保该对象至少处于活动状态,直到警报视图被取消。 这肯定会奏效,但可能会有太多工作......

以下是我提出的建议; IMO它更简单,并且不需要任何thirdParty库或每个UIAlertView的ivar。只需一个额外的对象(@property (nonatomic, strong) NSArray *modalActions)来存储当前UIAlertView将导致执行的操作

显示UIAlertView并做出相应的反应

UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:alertTitle
                                                    message:@"Blah blah"
                                                   delegate:self
                                          cancelButtonTitle:@"Cancel"
                                          otherButtonTitles:b1, b2, b3, nil];
// Add one selector/action per button at the proper index
self.modalActions = @[
                   [NSNull null], // Because indexes of UIAlertView buttons start at 1
                   NSStringFromSelector(@selector(actionForAlertViewButton1)),
                   NSStringFromSelector(@selector(actionForAlertViewButton2)),
                   NSStringFromSelector(@selector(actionForAlertViewButton3))];
[alertView show];

委托方法:

- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex
{
    if (alertView.cancelButtonIndex != buttonIndex) {
        [self performModalActionAtIndex:buttonIndex];
    }
}

实际执行操作的部分:

- (void)performModalActionAtIndex:(NSInteger)index
{
    if (-1 < index && index < self.modalActions.count &&
        [self.modalActions[index] isKindOfClass:[NSString class]]) {
        SEL action = NSSelectorFromString(self.modalActions[index]);
        NSLog(@"action: %@", self.modalActions[index]);
        if ([self respondsToSelector:action]) {
// There is a situation with performSelector: in ARC.
// http://stackoverflow.com/questions/7017281/
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
        [self performSelector:action];
#pragma clang diagnostic pop
    }
    self.modalActions = nil;
}

也可以重用UIActionSheets

UIActionSheet *actionSheet = [[UIActionSheet alloc] initWithTitle:title
                                                         delegate:self
                                                cancelButtonTitle:cancelButton  
                                           destructiveButtonTitle:nil 
                                                otherButtonTitles:button1, button2, button3, nil];
// Similarly, add one action per button at the proper index
self.modalActions = @[
                    NSStringFromSelector(@selector(actionForActionSheetButton1)),
                    NSStringFromSelector(@selector(actionForActionSheetButton2)),
                    NSStringFromSelector(@selector(actionForActionSheetButton3))];

委托方法:

- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
{
    if (actionSheet.cancelButtonIndex != buttonIndex) {
        [self performModalActionAtIndex:buttonIndex];
    }
}

为什么会这样:

这有效是因为两个原因:

首先,我从未提出过两个同时拥有委托的UIAlertView。 (IMO你不应该,它看起来不太好)。其次,因为在我的情况下(作为90%的情况),动作的目标始终是同一个对象(在这种情况下:self)。即使您不满足上述条件,您甚至可以使用此方法进行一些修改:

  • 如果您同时显示两个或更多UIAlerViews或UIActionSheets(可能在iPad中)使用字典来存储与某个UIAlertView / UIActionSheet关联的一系列操作。

  • 如果操作的目标不是self,则需要在数组中存储对(目标和操作)。 (模拟UIButtons addTarget:action:...)的东西。

在任何一种情况下,为了存储目标和/或UIActionSheet / UIAlertView [NSValue valueWithNonretainedObject:]应该变得方便:)

答案 4 :(得分:1)

First of all you declare UIAlertViewDelegate in .h file after put below code in .m file

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

   if (buttonIndex == 1) 
    {
         //put button action which you want.
    }
}

答案 5 :(得分:0)

实施UIAlertViewDelegate并使用委托方法

- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
  if(buttonIndex == 0) {
    // Do something
  }
  else {
   // Do something
  }
}

答案 6 :(得分:0)

UIAlertView *alertView=[[UIAlertView alloc]initWithTitle:@"Data Saved" message:@"Choose more photos" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:Nil];
        [alertView show];
        [alertView release];


-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex{
    if(buttonIndex==0)
    {
        [self dismissModalViewControllerAnimated:YES];
    }
}

答案 7 :(得分:0)

在swift中: 我们可以使用这个小代码块

    let alert = UIAlertController(title: "Alert", message: "This is an alert message", preferredStyle: UIAlertControllerStyle.Alert)

    let action = UIAlertAction(title: "OK", style: UIAlertActionStyle.Default, handler: {(action:UIAlertAction) in print("This is in alert block")
    })

    alert.addAction(action)
    self.presentViewController(alert, animated: true, completion: nil)