Pregunta

Estoy seguro de que esto es en la documentación de Apple o debe haber sido contestada en algún lugar de este foro, ya que parece tan básico, pero no lo encontró ni una solución especialmente elegante a mí mismo.

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 está siendo editando cuando se toca el botón de retroceso, el método viewWillAppear de la vista original se llama antes de cualquiera de los métodos UITextField delegado de textFieldShouldEndEditing o textFieldDidEndEditing, o el IB ligado método textFieldEditingEnded acción se llama.

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 :

- (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 la pila del controlador ... el botón de retroceso ha sido empujado
  [...] Introducción de vista aparecerá de vista maestra
  [...] En textFieldShouldEndEditing
  [...] En textFieldEditingEnded
  [...] En textFieldDidEndEditing

Quiero conjunto self.editedObject.name = nameField.text antes que la etiqueta se encuentra en viewWillAppear para la UIViewController.

Yo pensaba en el método viewWillDisappear para la EditViewController comprobación para ver si alguno de mis campos de texto son actualmente el primer nivel de respuesta y si es así conseguir su texto y almacenarlo, pero esto parece una chapuza de tal manera que será un dolor de mantener si añado o cambio campos de texto.

También puede implementar el textFieldEditingChanged IB vinculado acción para establecer el texto en el objeto editado después de cada golpe de teclado, pero esto es también un poco de sobrecarga ya que tengo que averiguar qué campo de texto que estoy en cada golpe de teclado (recuerda que sólo mostró name pero hay un montón de ellos).

Todo lo que necesito es para la edición que se terminó o para conocer la edición se terminó antes de viewWillAppear se llama en el UIViewController por lo que el nameFieldLabel está configurado correctamente.

¿Fue útil?

Solución

OK, 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, sólo una línea de código añade. En el método de la viewWillDisappear EditViewContorller simplemente añadido:

    [self.view.window endEditing: YES];

Ahora textFieldShouldEndEditing, textFieldEditingEnded y textFieldDidEndEditing todo lo despidan antes de que el viewWillAppear de la vista maestra lo hace.

Así que ahora las miradas método viewWillDisappear como:

- (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 ayudarme a pensar en esto.

Otros consejos

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

Me gustaría pensar que desde una perspectiva UX, se deberían mostrar una alerta para determinar si el usuario quiere cancelar la acción de edición que estaban en el medio de antes de salir de la vista actual.

Al alertar al usuario, se puede ver si se pulsa el botón por accidente o si lo hicieron deciden abandonar la vista, tomar la acción apropiada.

// 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;
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top