2009-02-21 12 views
5

Necesito ejecutar un par de validaciones que dependen de las decisiones del usuario (por ejemplo, si apruebo una compra superior al límite de gasto) y denegar la acción "finalizada" si falla.UIAlertView verdaderamente modal en iPhone?

Sin embargo, parece que no es posible tener una acción verdaderamente modal como con otros idiomas (como showmessage, alert(), etc.) y todo es por delegados.

Pero entonces no sé qué hacer. Si el usuario presiona el botón "listo", el programa pregunta "¿Está seguro de esto?" y él dice "cancelar", ¡el flujo continúa y la vista es empujada hacia atrás!

¿Cómo se resuelve esto en el mundo del cacao?

Respuesta

7

La solución es para no combatirlo, simplemente divida su lógica en dos partes. Si el usuario hace clic en cancelar, no ejecute la segunda parte. Si el usuario hace clic en Aceptar/Continuar, ejecuta la segunda parte.

El principal problema causado por el bloqueo del hilo principal es que el hilo principal es el que maneja los eventos. La forma clásica de manejar eventos puede presentar errores de manejo de eventos extraños, porque no tiene un bucle de evento, sino que tiene múltiples bucles de eventos incrustados uno dentro del otro.

Al usar delegados, puede utilizar un bucle de evento (invocado a través de UIApplicationMain), y no tener ninguno de estos eventos que manejan rarezas.

+3

En otras palabras, reorganice completamente su código, y ore para que el día anterior a la fecha programada para la liberación no haga que su usuario regrese pidiendo una verificación justo en medio de un cálculo grande y complicado con un montón de variables locales. – GeneralMike

+1

+1 por no combatirlo. –

0

Mantenga el estado de la aplicación en otro lugar que no sean las variables de la función. Por ejemplo, en una de mis aplicaciones, hay una cadena de perfil que indica si han aceptado o no la política de privacidad.

0

Acabo de toparme con esta pregunta como una pregunta de MonoTouch, y mientras investigaba una solución, encontré esta pregunta abierta.

La respuesta corta es que sí, esto es posible. El siguiente ejemplo muestra cómo se hace esto con MonoTouch y C# en el iPhone, pero el mismo principio se aplica a Objective-C.

Para hacer esto, lo que puede hacer es ejecutar el mainloop manualmente. No he logrado detener el mainloop directamente, así que en lugar de eso corro el mainloop por 0.5 segundos y espero hasta que el usuario responda.

La función siguiente muestra cómo se puede implementar una consulta modal con el enfoque anterior:

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

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

Con él se pueden hacer cosas como:

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

Esto funciona mucho mejor que el método privado [alerta setRunsModal: YES] porque con la implementación de Apple la primera alerta se cancela cuando se muestra la segunda. Sin embargo, con esta implementación puede tener alertas anidadas. – malhal

0

Estoy de acuerdo con NilObject en que generalmente no debes pelear, y generalmente no lo hago. Pero yo estoy usando el marco AddressBookUI y cuando estoy en el método delegado,

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

realmente me gustaría para advertir al usuario de que son, por ejemplo, va a salir de la aplicación al hacer clic en una dirección, que se dispara fuera de la aplicación del mapa. Utilicé MapKit para hacer mi propio mapa, pero no tengo la paciencia para reproducir la aplicación de mapas completa (permitiendo que el usuario obtenga direcciones de otras direcciones), y he recurrido a dejar que shouldPerformDefaultAction haga su trabajo y arranque la aplicación de mapas, pero no tengo forma de advertir al usuario que está abandonando la aplicación.

Realmente me gustaría que Apple proporcionara un modelo UIAlertView muy básico en lugar de hackearlo. Esto es tonto