2010-10-31 7 views
13

Estoy seguro de que esto está en la documentación de Apple o debe haber sido respondido en algún lugar de este foro, ya que parece muy básico, pero no pude encontrarlo ni tampoco una solución particularmente elegante.Almacenamiento de contenido de UITextField antes de ver pops

Lo que tengo es un UIViewController que empuja una vista de edición en su pila de navegación. La vista de edición tiene un montón de UITextFields en ella. Si uno de ellos se está editando cuando se toca el botón Atrás, se llama al método ViewWillAppear de la vista original antes de que se invoquen los métodos delegados UITextField textFieldShouldEndEditing o textFieldDidEndEditing o el método de acción enlazado IB textFieldEditingEnded.

Aquí hay un código que espero que sea más claro:

En el UIViewController:

- (void) viewWillAppear: (BOOL) animated { 
    [super viewWillAppear: animated]; 
    NSLog(@"Entering view will appear for master view"); 
    nameLabelField.text = objectToEdit.name; 
} 
- (IBAction) editMyObject: (id) sender { 
    NSLog(@"Editing the object"); 
    EditViewController *evc = [[EditViewController alloc] initWithNibName: @"EditTableView" bundle: nil]; 
    evc.editedObject = objectToEdit; 
    [self.navigationController pushViewController: evc animated: YES]; 
    [evc release]; 
} 

En el EditViewController < UITextFieldDelegate>:

- (void) viewWillAppear: (BOOL) animated { 
    [super viewWillAppear: animated]; 
    nameField.text = editedObject.name; 
} 
- (void) viewWillDisappear: (BOOL) animated { 
    [super viewWillDisappear: animated]; 
    NSLog(@"In viewWillDisappear"); 
    if([self.navigationController.viewControllers indexOfObject: self] == NSNotFound) { 
     NSLog(@"-- We are not in controller stack... the back button has been pushed"); 
    } 
} 
- (BOOL) textFieldShouldEndEditing: (UITextField *) textField { 
    NSLog(@"In textFieldShouldEndEditing"); 
    // Store text field value here??? 
    // editedObject.name = nameField.text; 
    return YES; 
} 
- (void) textFieldDidEndEditing: (UITextField *) textField { 
    NSLog(@"In textFieldDidEndEditing"); 
    // Store text field value here??? 
    // editedObject.name = nameField.text; 
} 
- (IBAction) textFieldEditingEnded: (id) sender { 
    NSLog(@"In textFieldEditingEnded"); 
    // Store text field value here??? 
    // editedObject.name = nameField.text; 
} 

El registro termina con :

[...] Entrando vista aparecerá de vista maestra
[...] Edición del objeto
[...] En viewWillDisappear
[...] - No estamos en pila controlador .. . el botón de retroceso ha sido empujado
[...] Entrando vista aparecerá de vista maestra
[...] En textFieldShouldEndEditing
[...] En textFieldEditingEnded
[...] En textFieldDidEndEditing

Quiero establecer self.editedObject.name = nameField.text antes de que la etiqueta se establezca en viewWillAppear para el UIViewController.

Pensé en el método viewWillDisappear para la comprobación de EditViewController para ver si alguno de mis campos de texto es actualmente el primero en responder y, si es así, obtener su texto y almacenarlo, pero esto parece un error que será un dolor para mantener si agrego o cambio campos de texto.

También puedo implementar la acción vinculada textFieldEditingChanged IB para establecer el texto en el objeto editado después de cada pulsación de tecla, pero esto también es un poco elevado ya que tengo que descubrir qué campo de texto estoy en cada pulsación (recuerde solo mostró name pero hay un montón de ellos).

Todo lo que necesito es que termine la edición o que la edición finalice antes de que se llame a viewWillAppear en el UIViewController para que el nombreFieldLabel esté configurado correctamente.

Respuesta

17

bien, me di cuenta de una solución sencilla después de un montón de navegación en Internet, Lectura, y la lectura manual. Era, como sospechaba, muy simple, solo se agregó una línea de código. En el método de la EditViewContorller viewWillDisappear simplemente agregué:

[self.view.window endEditing: YES]; 

ahora textFieldShouldEndEditing, textFieldEditingEnded y textFieldDidEndEditing todo Obtendrá disparó antes de la viewWillAppear de la vista maestra hace.

Así que ahora el método viewWillDisappear parece:

- (void) viewWillDisappear: (BOOL) animated { 
    [super viewWillDisappear: animated]; 
    NSLog(@"In viewWillDisappear"); 
    // Force any text fields that might be being edited to end so the text is stored 
    [self.view.window endEditing: YES]; 
} 

y ya los métodos establecidos para manejar el 'Volver' en el teclado también manejar el botón 'Atrás' en el controlador de navegación.

Gracias Aaron y Jeff por su ayuda y por ayudarme a pensar en esto.

+0

Gracias por su respuesta. También encontré que es la respuesta a esta pregunta: http://stackoverflow.com/questions/11319144/ios-xcode-crashed-after-typing-in-texts-in-uitextfield-and-go-back-nsisobject/ 11364617 # 11364617 – zekel

+0

¡Muchas gracias! Esto me estaba volviendo loco. Intuitivamente, me gustaría ver esto como el comportamiento predeterminado. – guptron

+0

Esto no funciona para mí, la transición ocurre antes de 'viewWillDisappear': ( – RnMss

0

¿Por qué no simplemente crear su propio botón Atrás con esa lógica en su método de acción?

+0

Gracias por la sugerencia Jeff. Esto puede ser lo que tengo que hacer, pero pierdo la interfaz de usuario del botón que aparece en el nativo con el extremo puntiagudo, a menos que haga un montón de trabajo creando un botón personalizado haciendo un archivo PNG para él, etc., etc. Estoy dispuesto a hacer eso si es necesario, para obtener la funcionalidad, pero espero algo que me falta solo para agregar a mi código. – LavaSlider

-1

Creo que desde una perspectiva de UX, debería mostrar una alerta para determinar si el usuario desea cancelar la acción de edición en la que se encontraban antes de salir de la vista actual.

Al alertar al usuario, puede ver si presionan el botón por accidente o si deciden abandonar la vista, tome las medidas adecuadas.

// add this to the field(s) to be edited, selector will be called as the changes 
// are being made... still difficult to handle a cancel, but should work 
[objectToEdit addTarget:self action:@selector(updateNameField:) 
         forControlEvents:UIControlEventEditingChanged]; 

código adicional aquí ...

// the method called to update object from parent view 
- (void)updateNameField:(id)sender { 
    <OBJECT TO UPDATE>.text = ((UITextField *)sender).text; 
} 
+0

Estaría bien con eso. Realmente estaba pensando que sería un botón de retroceso intencional ... ¿por qué presionar Hecho y luego Atrás? Supongo que requiere que impida el "Atrás" accidental. Pero esto no proporciona ninguna ayuda ya que no tengo forma de saber si presentar la alerta ya que no sé qué o si un campo de texto está en proceso de edición. – LavaSlider

+0

@LavaSlider ver ediciones, para hacer algo como textFieldEditingChanged, usted estaba discutiendo –

+0

@LavaSlider no es demasiado difícil implementar algo como textFieldEditingChanged. Ver las ediciones anteriores para la solución –

Cuestiones relacionadas