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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7397095/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 21:29:33  来源:igfitidea点击:

How to write event handlers for buttons in UIAlertView?

objective-ciosuialertview

提问by Ravi

Say I have a alert view like follows in obj c

假设我在 obj c 中有一个如下所示的警报视图

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

Now we have 2 buttons on the alert view (Ok & Download), how to write an event handler for the Download one?

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

回答by Chetan Bhalara

First you will need to add the UIAlertViewDelegate to your header file like below:

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

Header file (.h)

头文件 (.h)

@interface YourViewController : UIViewController<UIAlertViewDelegate> 

Implementation File (.m)

实施文件 (.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
    }
}

回答by zoul

Now that most iOS devices have firmare versions with blocks support it's an anachronism to use the clumsy callback API to handle button presses. Blocks are the way to go, see for example the Lambda Alert classes on GitHub:

既然大多数 iOS 设备都有带有块支持的固件版本,使用笨拙的回调 API 来处理按钮按下是不合时宜的。块是要走的路,例如参见GitHub 上Lambda Alert 类

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

回答by Guillermo Ortega

Declare your UIAlertViews as known.

将您的 UIAlertViews 声明为已知。

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

[alertLogout show]; 

[alertLogout release];

set delegate to self and implement this method.

将委托设置为 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) {

        }
    }
}

回答by nacho4d

Stack's and Guillermo Ortega's answer is probably what you would use with a couple of UIAlertView but not for ten. I use to use BlocksKitwhich is kind of the same as Lambda stuff which is what soul suggested. That is a good option too, although if you have too many nested blocks you will start seeing the demerits of it (Aside from the fact you will be relying in another library).

Stack 和 Guillermo Ortega 的回答可能是你会用几个 UIAlertView 但不是十个的答案。我过去常常使用BlocksKit,它与灵魂建议的 Lambda 内容有点相似。这也是一个不错的选择,尽管如果您有太多嵌套块,您将开始看到它的缺点(除了您将依赖另一个库的事实)。

The usual way of handling several stuff would be to have a handler object. ( @interface MyAlertViewDelegate : NSObject <UIAlertViewDelegate> @end) make that object the delegate of the alert view and make sure the object is alive at least until the alert view is dismissed. This will certainly work, but could be too much work...

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

What follows is what I came up with; IMO it is simpler and there is no need of any thirdParty library, or an ivar per UIAlertView. Just one extra object (@property (nonatomic, strong) NSArray *modalActions) to store the actions the current UIAlertView will cause to perform

接下来是我想出的;IMO 更简单,不需要任何第三方库,也不需要每个 UIAlertView 的 ivar。只需要一个额外的对象 ( @property (nonatomic, strong) NSArray *modalActions) 来存储当前 UIAlertView 将导致执行的操作

Showing an UIAlertView and reacting accordingly

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

The delegate method:

委托方法:

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

The part that actually performs the action:

实际执行动作的部分:

- (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;
}

Reusable for UIActionSheets too

也可用于 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))];

The delegate method:

委托方法:

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

Why this works:

为什么这样做:

This works because of two reasons:

这有两个原因:

First, I never present two UIAlertView that have a delegate at the same time. (IMO you should't, it doesn't look good). Second, because in my case (as 90% of the cases) the target of the actions is always the same object (in this case: self). Even if you don't meet above conditions you can even use this approach with some modifications:

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

  • If you show two or more UIAlerViews or UIActionSheets at the same time (possible in the iPad) Use a dictionary with to store one array of actions associated with a certain UIAlertView/UIActionSheet.

  • If the target of the actions is not self, they you need to store pairs (target and the action) in the array. (Something to simulate UIButtons addTarget:action:...).

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

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

In either case, for storing the target and/or UIActionSheet/UIAlertView [NSValue valueWithNonretainedObject:]should become handy :)

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

回答by Nikunj Jadav

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

回答by visakh7

Implement the UIAlertViewDelegateand make use of the delegate method

实现UIAlertViewDelegate并使用委托方法

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

回答by user2131610

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

回答by Mr. Tann

in swift: we can use this little block of code

迅速:我们可以使用这个小代码块

    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)