it-swarm.it

Come scrivere i gestori di eventi per i pulsanti in UIAlertView?

Supponiamo di avere una vista di avviso come segue in obj c

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

Ora abbiamo 2 pulsanti nella visualizzazione degli avvisi (Ok e download), come scrivere un gestore di eventi per il Download?

22
Ravi

Per prima cosa dovrai aggiungere UIAlertViewDelegate al tuo file di intestazione come di seguito:

File di intestazione (.h)

@interface YourViewController : UIViewController<UIAlertViewDelegate> 

File di implementazione (.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

Ora che la maggior parte dei dispositivi iOS ha versioni fisse con blocchi supportati, è un anacronismo utilizzare la goffa API callback per gestire le pressioni dei pulsanti. I blocchi sono la strada da percorrere, vedi ad esempio le classi Lambda Alert su 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

Dichiara le tue UIAlertViews come note.

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

[alertLogout show]; 

[alertLogout release];

impostare il delegato su se stesso e implementare questo metodo.

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

La risposta di Stack e Guillermo Ortega è probabilmente quella che usereste con un paio di UIAlertView ma non per dieci. Io uso per usare BlocksKit che è il tipo della roba Lambda che è ciò che l'anima suggeriva. Anche questa è una buona opzione, anche se se hai troppi blocchi nidificati inizierai a vederne i demeriti (a parte il fatto che ti affidi a un'altra libreria).

Il solito modo di gestire diverse cose sarebbe avere un oggetto gestore. (@interface MyAlertViewDelegate : NSObject <UIAlertViewDelegate> @end) rende quell'oggetto il delegato della vista di avviso e si assicura che l'oggetto sia vivo almeno fino a quando la vista di avviso non viene chiusa Questo funzionerà sicuramente, ma potrebbe essere troppo lavoro ...

Quello che segue è ciò che mi è venuto in mente; IMO è più semplice e non c'è bisogno di alcuna libreria di terze parti o di ivar per UIAlertView. Solo un oggetto extra (@property (nonatomic, strong) NSArray *modalActions) per memorizzare le azioni che l'attuale UIAlertView causerà

Mostrare un UIAlertView e reagire di conseguenza

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

Il metodo delegato:

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

La parte che esegue effettivamente l'azione:

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

Riutilizzabile anche per 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))];

Il metodo delegato:

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

Perché questo funziona:

Questo funziona per due motivi:

Innanzitutto, non presenterò mai due UIAlertView che hanno un delegato allo stesso tempo. (IMO dovresti, non sembra buono). Secondo, perché nel mio caso (come il 90% dei casi) il target delle azioni è sempre lo stesso oggetto (in questo caso: self). Anche se non rispetti le condizioni sopra descritte puoi addirittura utilizzare questo approccio con alcune modifiche:

  • Se si visualizzano due o più UIAlerViews o UIActionSheets contemporaneamente (possibile nell'iPad) Utilizzare un dizionario con per memorizzare una serie di azioni associate a un determinato UIAlertView/UIActionSheet.

  • Se il target delle azioni non è self, è necessario memorizzare coppie (target e azione) nella matrice. (Qualcosa per simulare UIButtons addTarget:action:...).

In entrambi i casi, per memorizzare il target e/o UIActionSheet/UIAlertView [NSValue valueWithNonretainedObject:] dovrebbe diventare utile :)

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

Implementare UIAlertViewDelegate e utilizzare il metodo delegate

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

in Swift: possiamo usare questo piccolo blocco di codice 

    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