iphone UIAlertView Modale

È possibile presentare un UIAlertView e non continuare l’esecuzione del resto del codice, e in questo metodo fino a quando l’utente risponde l’avviso?

Grazie in anticipo.

  • Non fermare il codice di dire che non sarebbe in grado di rispondere all’utente premendo il tasto?
InformationsquelleAutor ghiboz | 2010-11-22

 

5 Replies
  1. 20

    Credo arresto codice che si voleva fare è interrompere il dispositivo eseguire il successivo codice che hai scritto dopo il alertview

    Per che basta rimuovere il vostro codice dopo il alertview e mettere il codice nel alertview delegato

    -(void) yourFunction
    {
         //Some code
         UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"" message:@"Your Message" delegate:self cancelButtonTitle:nil otherButtonTitles:@"OK", nil];
                [alert show];
                [alert release];
         //Remove all your code from here put it in the delegate of alertview
    }
    -(void)alertView:(UIAlertView *)alertView willDismissWithButtonIndex:    (NSInteger)buttonIndex 
    {
    if(buttonIndex==0)
        {
            //Code that will run after you press ok button 
        }
    }

    Non dimenticare di includere UIAlertViewDelegate nel .h file

    • Ugh. Un pò triste, questo è il modo migliore per affrontare questo. “Oops, mi sono appena reso conto deve assicurarsi che l’utente vuole fare questo prima di eseguire il codice. Ora mi permetta di riorganizzare tutto il mio codice…”
    • Triste, ma più asincrona.
    • Che cosa succede se ho un parametro per ‘yourFunction’? Come posso portare il delegato?
    • Si potrebbe provare un avviso vista che utilizza blocchi invece di delegati. Vedere github.com/ryanmaxwell/UIAlertView-Blocks
  2. 9

    Una risposta è già stata accettata, ma faccio notare per chi viene di fronte a questa domanda che, mentre non si deve usare questo per il normale avviso di movimentazione, in determinate circostanze, potrebbe essere necessario evitare che l’attuale percorso di esecuzione di continuare, mentre un avviso viene presentato. Per farlo, si può girare in esecuzione di loop per il thread principale.

    Utilizzare questo approccio per gestire errori fatali che voglio presentare all’utente prima di schiantarsi. In tal caso, qualcosa di catastrofico è successo, quindi non ho voglia di tornare dal metodo che ha causato l’errore, che potrebbe consentire ad altri l’esecuzione di codice con uno stato non valido e, per esempio, dati corrotti.

    Notare che questo non prevenire gli eventi trattati o bloccare altri thread in esecuzione, ma dal momento che stiamo presentando un avviso che svolge essenzialmente l’interfaccia, eventi in genere dovrebbe essere limitato a tale avviso.

    //Present a message to the user and crash
    -(void)crashNicely {
    
      //create an alert
      UIAlertView *alert = ...;
    
      //become the alert delegate
      alert.delegate = self;
    
      //display your alert first
      [alert show];
    
      //spin in the run loop forever, your alert delegate will still be invoked
      while(TRUE) [[NSRunLoop currentRunLoop] runUntilDate:[NSDate distantFuture]];
    
      //this line will never be reached
      NSLog(@"Don't run me, and don't return.");
    
    }
    
    //Alert view delegate
    - (void)alertView:(UIAlertView *)alertView willDismissWithButtonIndex:(NSInteger)buttonIndex {
      abort(); //crash here
    }
    • thx. Non so perché gli altri la risposta è stata accettata, ma solo la soluzione dose di lavoro.
    • Sembra che non funziona su XCode 5
  3. 1

    No, ma la soluzione semplice è quello di dividere il codice nel punto in cui si presenti la UIAlertView – e iniziare la seconda parte dal tuo metodo di delegato quando l’avviso viene respinto.

  4. 1

    Ho appena imbattuto in questa domanda per MonoTouch, e cercando di trovare una risposta precedente imbattuto in questo problema aperto.

    Sì, è possibile. Il seguente esempio, in C# mostra come si può fare con MonoTouch, un Obiettivo-C versione di questo dovrebbe essere facile da scrivere:

    Per fare questo, cosa si può fare è quello di eseguire il mainloop manualmente. Io non sono riusciti a fermare il mainloop direttamente, così ho invece eseguire il mainloop per 0,5 secondi e attendere fino a quando l’utente risponde.

    La funzione riportata di seguito viene illustrato come è possibile implementare un modale query con l’approccio sopra descritto:

    int WaitForClick ()
    {
        int clicked = -1;
        var x = new UIAlertView ("Title", "Message",  null, "Cancel", "OK", "Perhaps");
        x.Show ();
        bool done = false;
        x.Clicked += (sender, buttonArgs) => {
            Console.WriteLine ("User clicked on {0}", buttonArgs.ButtonIndex);
        clicked = buttonArgs.ButtonIndex;
        };    
        while (clicked == -1){
            NSRunLoop.Current.RunUntil (NSDate.FromTimeIntervalSinceNow (0.5));
            Console.WriteLine ("Waiting for another 0.5 seconds");
        }
    
        Console.WriteLine ("The user clicked {0}", clicked);
        return clicked;
    }
    • Questo a quanto pare funziona più con iOS 5.
    • Sì, lo fa. Di utilizzarlo.
    • Potresti postare il codice che si utilizza? Non ho familiarità con C# e poco familiare con Objective-C, quindi sto avendo problemi nella conversione di questo per qualcosa che posso utilizzare.
    • Sto usando esattamente il codice postato sopra da Miguel.
    • Questa tecnica non funziona più in iOS7, a causa di un bug in cui il UIAlertView delegato non potrà mai essere chiamato una volta il RunLoop è iniziato. Per dettagli: stackoverflow.com/questions/18607349/…
  5. 1

    Se il codice che deve attendere è tutto lo stesso metodo (o può essere), blocchi può essere un’altra opzione. Ho creato un UIAlertView sottoclasse di gestire questo. Basta tenere a mente che l’esecuzione continuerà passato [alert show] chiamata; questo ti dà solo un modo per passare insieme il vostro stack variabili senza fare nuove tra le variabili di classe. Inoltre, se non si ha già familiarità con Objective-C i blocchi, si consiglia di leggere la documentazione su di esso; ci sono alcuni trucchi e qualche strana sintassi si dovrebbe essere a conoscenza.

    Va qualcosa come questo:

    typedef void (^MyAlertResult)(NSInteger clickedButtonIndex);
    
    @interface MyBlockAlert : UIAlertView
    {
        MyAlertResult finishedBlock;
    }
    - (void) showWithCompletionBlock:(MyAlertResult)block;
    ...
    
    - (void) showWithCompletionBlock:(MyAlertResult)block
    {
        self.delegate = self;
        finishedBlock = [block copy];
        [self show];
    }
    
    - (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
    {
        finishedBlock(buttonIndex);
        [finishedBlock release];
        finishedBlock = nil;
    }

    utilizzati come questo:

    __block NSArray* arrayOfDeletes; //set to something
    MyBlockAlert* areYouSureAlert = [[MyBlockAlert alloc] initWithTitle:@"Really delete?" message:@"Message" delegate:nil cancelButtonTitle:@"Cancel" otherButtonTitles:@"Delete", nil];
    
    [arrayOfDeletes retain]; //Make sure retain count is +1
    
    [areYouSureAlert showWithCompletionBlock:
    ^(NSInteger clickedButtonIndex)
    {
        if (clickedButtonIndex == 1)
        {
            //Clicked okay, perform delete
        }
        [arrayOfDeletes release];
    }];
    [areYouSureAlert release];

    Questa è stata una rapida attuazione, quindi sentitevi liberi di trovare eventuali bug, ma si ottiene l’idea.

    • Qualcosa lungo queste linee (blocchi) è più pulito e non richiede delegati in tutto il luogo.

Lascia un commento