web-dev-qa-db-fra.com

Comment écrire des gestionnaires d'événements pour les boutons dans UIAlertView?

Dites que j'ai une vue alerte comme suit dans obj c

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

Maintenant, nous avons 2 boutons sur la vue d'alerte (Ok & Télécharger), comment écrire un gestionnaire d'événements pour le Télécharger?

22
Ravi

Vous devez d’abord ajouter UIAlertViewDelegate à votre fichier d’en-tête comme ci-dessous:

Fichier d'en-tête (.h)

@interface YourViewController : UIViewController<UIAlertViewDelegate> 

Fichier d'implémentation (.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
    }
}
45
Chetan Bhalara

Maintenant que la plupart des appareils iOS ont des versions firmare avec des blocs supportés, c’est un anachronisme d’utiliser l’API de rappel maladroite pour gérer les pressions sur les boutons. Les blocs sont la voie à suivre, voir par exemple les classes Lambda Alert sur 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];
5
zoul

Déclarez votre UIAlertViews comme connu.

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

[alertLogout show]; 

[alertLogout release];

définir délégué à soi-même et implémenter cette méthode.

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

        }
    }
}
2
Guillermo Ortega

La réponse de Stack et Guillermo Ortega est probablement celle que vous utiliseriez avec deux UIAlertView, mais pas pour dix. J'avais l'habitude d'utiliser BlocksKit , qui est un peu la même chose que Lambda, c'est ce que soul a suggéré. C’est également une bonne option, mais si vous avez trop de blocs imbriqués, vous commencerez à en voir les inconvénients (à part le fait que vous utiliserez une autre bibliothèque).

La manière habituelle de gérer plusieurs choses serait d'avoir un objet de gestionnaire. (@interface MyAlertViewDelegate : NSObject <UIAlertViewDelegate> @end) transforme cet objet en délégué de la vue des alertes et veille à ce qu'il soit en vie au moins jusqu'à ce que la vue des alertes soit supprimée.

Ce qui suit est ce que je suis venu avec; IMO, c'est plus simple et il n'y a pas besoin de bibliothèque tierce, ni d'ivar par UIAlertView. Juste un objet supplémentaire (@property (nonatomic, strong) NSArray *modalActions) pour stocker les actions que UIAlertView actuelle va effectuer

Montrer un UIAlertView et réagir en conséquence

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

La méthode déléguée:

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

La partie qui effectue réellement l'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;
}

Réutilisable pour UIActionSheets aussi

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

La méthode déléguée:

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

Pourquoi ça marche:

Cela fonctionne pour deux raisons:

Premièrement, je ne présente jamais deux UIAlertView ayant un délégué en même temps. (IMO vous ne devriez pas, ça n'a pas l'air bien). Deuxièmement, parce que dans mon cas (dans 90% des cas), la cible des actions est toujours le même objet (dans ce cas: self). Même si vous ne remplissez pas les conditions ci-dessus, vous pouvez même utiliser cette approche avec quelques modifications:

  • Si vous affichez plusieurs UIAlerViews ou UIActionSheets en même temps (possible sur l'iPad) Utilisez un dictionnaire avec pour stocker un tableau d'actions associé à un certain UIAlertView/UIActionSheet.

  • Si la cible des actions n'est pas self, vous devez stocker des paires (cible et action) dans le tableau. (Quelque chose à simuler UIButtons addTarget:action:...).

Dans les deux cas, pour stocker la cible et/ou UIActionSheet/UIAlertView [NSValue valueWithNonretainedObject:] devrait devenir pratique :)

2
nacho4d
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.
    }
}
1
Nikunj Jadav

Implémentez la UIAlertViewDelegate et utilisez la méthode delegate

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

dans Swift: nous pouvons utiliser ce petit bloc de 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)
0
Mr. Tann
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
user2131610