2010-06-25 25 views
5

Estoy trabajando en una vista que tiene múltiples objetos UITextField. Mi controlador de vista sirve como UITextFieldDelegate, y he implementado el método (BOOL)textFieldShouldEndEditing:(UITextField *)textField para guardar y validar el registro que se muestra.textFieldShouldEndEditing llamado varias veces

Si el usuario hace clic en el botón "Hecho" después de editar un elemento y el guardar/validar falla, aparece un UIAlertView y el usuario se mantiene en el UITextField que falla la validación.

Mi problema es el siguiente - cuando un usuario hace clic en el UITextField que fallará Guardar/validación en otro de los UITextField s, entonces el método (BOOL)textFieldShouldEndEditing:(UITextField *)textField se llama varias veces, y el UIAlertView aparece varias veces.

¿Por qué se llama (BOOL)textFieldShouldEndEditing:(UITextField *)textField una vez cuando el usuario hace clic en "Listo" en el teclado, pero se le llama varias veces cuando el usuario hace clic en otro UITextField?

Aquí está mi código:

- (BOOL)textFieldShouldEndEditing:(UITextField *)textField { 
    NSLog(@"textFieldShouldEndEditing called by textField with text=%@", textField.text); 

    currentItem.nameOrNumber = nameOrNumber.text; 

    // Try to save the managed object. 
    NSError *error = nil; 
    if (![[currentItem managedObjectContext] save:&error]) {   
     UIAlertView *errorAlert = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Uh Oh!",@"") 
                  message:[error localizedDescription] 
                  delegate:self 
                cancelButtonTitle:NSLocalizedString(@"OK",@"") 
                otherButtonTitles:nil]; 
     [errorAlert show]; 
     [errorAlert release]; 
     shouldEnd = NO; 
    } 

    return shouldEnd; 
} 

Respuesta

3

Creo que su problema proviene de la orden en el que se denominan métodos de campo de texto cuando se está editando un campo de texto y toque directamente sobre otra.

Si no estoy equivocado, debería ser algo como esto (que está editando en A y pulse sobre B)

  • textFieldShouldBeginEditing para el campo B
  • textFieldShouldEndEditing de campo Un
  • textFieldDidEndEditing para el campo Un
  • textFieldDidBeginEditing para el campo B

Así que cuando yo Está en el método textFieldShouldEndEditing, el campo de texto B ya se convirtió en el primer respondedor. Así que cuando haces aparecer el UIAlertView, B pierde el foco y llama al textFieldShouldEndEditing también!

Esto también ha sido un problema para mí cuando quería mostrar una vista cuando un textField comenzaba a editarse. La solución que encontré fue crear una variable de clase booleana que indica si actualmente estoy cambiando de un campo de texto a otro. Configuré en TRUE en textFieldShouldBeginEditing y en FALSE en textFieldDidBeginEditing. Cuando está en textFieldShouldEndEditing, si está configurado en TRUE, significa que el usuario ha tocado directamente en otro textField. Entonces solo tienes que encontrar la forma correcta de hacer tus pruebas solo una vez (quizás shouldEnditing debe devolver false o algo así).

0

Parece correcto que me llamen 2 veces por cada campo de prueba. ¿Por qué? Sólo pienso ... había pasado a mí también, y me refiero dolor de cabeza

no se puede hacer a algunos les gusta esta

- (BOOL)textFieldShouldEndEditing:(UITextField *)txtField{ 

if(i_dont_know){ 
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Title" 
                message:@"Message" 
                delegate:self 
              cancelButtonTitle:@"Ok" otherButtonTitles: nil]; 
    [alert show]; 
    [alert release]; 
    return false; 
} 

return true;} 

es que el espectáculo UIAlertView también está tratando de renunciar a la edición del campo de texto y llamando a esta función "textFieldShouldEndEditing:" ...

Así que mi manera de resolver esto fue agregar una variable miembro llamada "shouldEndEditing" en la interfaz de delaware, que es verdadera por defecto. Y después de "textFieldShouldEndEditing:" puede ser algo como esto.

- (BOOL)textFieldShouldEndEditing:(UITextField *)txtField{ 

if(shouldEndEditing == false) 
{ 
    shouldEndEditing = true; 
    return false; 
} 

if(i_dont_know){ 
    shouldEndEditing = false; 
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Title" 
                message:@"Message" 
                delegate:self 
              cancelButtonTitle:@"Ok" otherButtonTitles: nil]; 
    [alert show]; 
    [alert release]; 
    return false; 
} 

return true;} 

Buena suerte ...

1

Otra opción es dejar que el UIAlertView falsa una validación correcta y diferir la parte corregir a una última vez. Algo como esto:

- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex{ 
    double delayInSeconds = 0.; 
    self.currentTextField.text = @"Something that won't trigger validation error"; 
    dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC); 
    dispatch_after(popTime, dispatch_get_main_queue(), ^(void){ 
     // do what you need here 
    }); 
} 
0

¿No podría añadir etiquetas diferentes en cada TextView y comprobar la etiqueta en el textFieldShouldEndEditing? ¿O me he perdido el punto?

Cuestiones relacionadas