2009-02-21 8 views
5

Sono necessario eseguire un paio di convalide che dipendono dalle decisioni dell'utente (ad esempio, se approvare un acquisto al di sopra del limite di spesa) e negare l'azione "completata" se non riesce.UIAlertView veramente modale in iPhone?

Tuttavia, sembra che non sia possibile avere un'azione veramente modale come con altri linguaggi (come showmessage, alert(), ecc.) E tutto è delegato.

Ma poi non so cosa fare. Se l'utente preme il pulsante "completato", il programma chiede "Sei sicuro di questo?" e dice "cancella" il flusso continua e la vista viene respinta!

Come viene risolto nel mondo del cacao?

risposta

7

La soluzione è non combatterlo, basta rompere la logica in due parti. Se l'utente fa clic su Annulla, non eseguire la seconda parte. Se l'utente fa clic su OK/Continua, esegue la seconda parte.

Il problema principale causato dal blocco del thread principale è che il thread principale è ciò che gestisce gli eventi. Il modo classico di gestire gli eventi può introdurre strani bug di gestione degli eventi, perché non hai un ciclo di eventi, ma hai più loop di eventi incorporati l'uno nell'altro.

Utilizzando i delegati, è possibile utilizzare un ciclo di eventi (richiamato tramite UIApplicationMain) e non avere nessuna di queste stranezze relative alla gestione degli eventi.

+3

In altre parole, riorganizza completamente il tuo codice e prega che il giorno prima della tua pubblicazione non venga restituito all'utente che chiede una verifica nel bel mezzo di un calcolo grande e complicato con un gruppo di variabili locali. – GeneralMike

+1

+1 per non combatterlo. –

0

Mantiene lo stato dell'applicazione in un altro posto diverso dalle variabili nella funzione. Ad esempio, in una delle mie app, c'è una stringa del profilo che indica se hanno accettato o meno la politica sulla privacy.

0

Mi sono solo imbattuto in questa domanda come una domanda di MonoTouch e, mentre cercavo una soluzione, mi sono imbattuto in questa domanda aperta.

La risposta breve è che sì, questo è possibile. Il seguente esempio mostra come questo viene fatto con MonoTouch e C# su iPhone, ma lo stesso principio si applica a Objective-C.

Per fare ciò, è possibile eseguire manualmente il mainloop. Non sono riuscito a fermare direttamente il mainloop, quindi eseguo il mainloop per 0,5 secondi e aspetto che l'utente risponda.

La funzione seguente mostra come è possibile implementare una query modale con l'approccio di cui sopra:

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

Partenza: http://code.google.com/p/modal-uialertview-uiactionsheet/

Con esso si possono fare cose come:

UIActionSheet *actionSheet = [[UIActionSheet alloc] initWithTitle:nil delegate:nil cancelButtonTitle:@"Cancel" destructiveButtonTitle:@"Delete" otherButtonTitles:nil]; 
if ([actionSheet showModalInView:self.view] == actionSheet.destructiveButtonIndex) { 
    UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:nil message:@"Do you want to delete this file?" delegate:nil cancelButtonTitle:@"No" otherButtonTitles:@"Yes", nil]; 
    if ([alertView showModal]!= alertView.cancelButtonIndex) { 
     // Delete the file 
    } 
} 
+0

Funziona molto meglio del metodo privato [alert setRunsModal: YES] perché con l'implementazione di Apple il primo avviso viene annullato quando si mostra il secondo. Tuttavia con questa implementazione è possibile avere avvisi nidificati. – malhal

0

Sono d'accordo con NilObject che generalmente non dovresti combatterlo, e generalmente non lo faccio. Ma sto utilizzando il framework AddressBookUI e quando sono nel metodo delegato,

- (BOOL)unknownPersonViewController:(ABUnknownPersonViewController *)personViewController shouldPerformDefaultActionForPerson:(ABRecordRef)person property:(ABPropertyID)property identifier:(ABMultiValueIdentifier)identifier 

mi piacerebbe molto per avvertire l'utente che essi sono, per esempio, di andare a lasciare l'applicazione quando si fa clic su un indirizzo, che spegne l'app della mappa. Ho usato MapKit per fare la mia mappa, ma non ho la pazienza di riprodurre l'applicazione completa della mappa (lasciando che l'utente ottenga le indicazioni da qualche altro indirizzo), e ho fatto semplicemente il shouldPerformDefaultAction a fare il lavoro e accendere l'app della mappa, ma non ho modo di avvertire l'utente che sta lasciando l'app.

Vorrei davvero che Apple fornisse un modello base UIAlertView piuttosto che hackerarlo. Questo è sciocco.