Как написать обработчики событий для кнопок в UIAlertView? - PullRequest
22 голосов
/ 13 сентября 2011

Скажем, у меня есть представление предупреждений, как следует в obj c

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

Теперь у нас есть 2 кнопки в представлении предупреждений (Ok & Download), как написать обработчик событий для Download?1004 *

Ответы [ 8 ]

46 голосов
/ 13 сентября 2011

Сначала вам нужно добавить 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
    }
}
5 голосов
/ 13 сентября 2011

Теперь, когда большинство устройств iOS имеют устойчивые версии с поддержкой блоков, анахронизм заключается в использовании неуклюжего API обратного вызова для обработки нажатий кнопок.Блоки - это путь, смотри, например, классы Lambda Alert на 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 голосов
/ 14 мая 2013

Ответ стека и Гильермо Ортеги, вероятно, то, что вы бы использовали с парой UIAlertView, но не для десяти.Я использую, чтобы использовать BlocksKit , который похож на лямбда-материал, который предлагает душа.Это тоже хороший вариант, хотя, если у вас слишком много вложенных блоков, вы начнете видеть его недостатки (кроме того факта, что вы будете полагаться на другую библиотеку).

Обычный способ обработки нескольких вещейбудет иметь объект-обработчик.(@interface MyAlertViewDelegate : NSObject <UIAlertViewDelegate> @end) сделайте этот объект делегатом представления оповещения и убедитесь, что объект жив, по крайней мере, до тех пор, пока представление оповещения не будет отклонено.Это, безусловно, сработает, но может быть слишком много работы ...

Что следует из того, что я придумал;IMO - это проще, и нет необходимости в какой-либо библиотеке ThirdParty или ivar для UIAlertView.Всего один дополнительный объект (@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.
// /4844809/executeselector-mozhet-vyzvat-utechku-potomu-chto-ego-selektor-neizvesten
#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, то вам нужно хранить пары (targetи действие) в массиве.(Что-то для имитации кнопок UIB addTarget:action:...).

В любом случае для хранения цели и / или UIActionSheet / UIAlertView [NSValue valueWithNonretainedObject:] должно стать удобно:)

2 голосов
/ 09 февраля 2012

Объявите ваши UIAlertViews как известные.

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

[alertLogout show]; 

[alertLogout release];

установить делегата для себя и реализовать этот метод.

-(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) {

        }
    }
}
1 голос
/ 13 сентября 2011
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.
    }
}
0 голосов
/ 08 сентября 2016

в кратчайшие сроки: мы можем использовать этот маленький блок кода

    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)
0 голосов
/ 04 марта 2013
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];
    }
}
0 голосов
/ 13 сентября 2011

Реализация UIAlertViewDelegate и использование метода делегата

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