Cómo navegar a través de campos de texto (botones Siguiente/Listo)

Resuelto phx asked hace 54 años • 35 respuestas

¿Cómo puedo navegar por todos mis campos de texto con el botón "Siguiente" en el teclado del iPhone?

El último campo de texto debería cerrar el teclado.

Configuré los botones del IB (Siguiente/Listo) pero ahora estoy atascado.

Implementé la acción textFieldShouldReturn pero ahora los botones Siguiente y Listo cierran el teclado.

phx avatar Jan 01 '70 08:01 phx
Aceptado

En Cocoa para Mac OS X, tiene la siguiente cadena de respuesta, donde puede preguntarle al campo de texto qué control debe centrarse a continuación. Esto es lo que hace que funcione la tabulación entre campos de texto. Pero como los dispositivos iOS no tienen teclado, solo táctil, este concepto no ha sobrevivido a la transición a Cocoa Touch.

Esto se puede hacer fácilmente de todos modos, con dos suposiciones:

  1. Todos los "tabbable" UITextFieldestán en la misma vista principal.
  2. Su "orden de tabulación" está definido por la propiedad de etiqueta.

Suponiendo esto, puedes anular textFieldShouldReturn: como esto:

-(BOOL)textFieldShouldReturn:(UITextField*)textField
{
  NSInteger nextTag = textField.tag + 1;
  // Try to find next responder
  UIResponder* nextResponder = [textField.superview viewWithTag:nextTag];
  if (nextResponder) {
    // Found next responder, so set it.
    [nextResponder becomeFirstResponder];
  } else {
    // Not found, so remove keyboard.
    [textField resignFirstResponder];
  }
  return NO; // We do not want UITextField to insert line-breaks.
}

Agregue más código y las suposiciones también podrán ignorarse.

Rápido 4.0

 func textFieldShouldReturn(_ textField: UITextField) -> Bool {
    let nextTag = textField.tag + 1
    // Try to find next responder
    let nextResponder = textField.superview?.viewWithTag(nextTag) as UIResponder!

    if nextResponder != nil {
        // Found next responder, so set it
        nextResponder?.becomeFirstResponder()
    } else {
        // Not found, so remove keyboard
        textField.resignFirstResponder()
    }

    return false
}

Si la supervisión del campo de texto será UITableViewCell, el siguiente respondedor será

let nextResponder = textField.superview?.superview?.superview?.viewWithTag(nextTag) as UIResponder!
PeyloW avatar Aug 29 '2009 10:08 PeyloW

Hay una solución mucho más elegante que me dejó atónito la primera vez que la vi. Beneficios:

  • Más cerca de la implementación del campo de texto OSX, donde un campo de texto sabe dónde debe ir el foco a continuación
  • No depende de la configuración o el uso de etiquetas, que, en mi opinión, son frágiles para este caso de uso.
  • Se puede ampliar para que funcione con controles UITextFieldy UITextView, o con cualquier control de interfaz de usuario de entrada de teclado.
  • No satura su controlador de vista con código delegado UITextField repetitivo
  • Se integra muy bien con IB y se puede configurar mediante la opción familiar de arrastrar y soltar para conectar tomas de corriente.

Cree una subclase UITextField que tenga una IBOutletpropiedad llamada nextField. Aquí está el encabezado:

@interface SOTextField : UITextField

@property (weak, nonatomic) IBOutlet UITextField *nextField; 

@end

Y aquí está la implementación:

@implementation SOTextField

@end

En su controlador de vista, creará el -textFieldShouldReturn:método delegado:

- (BOOL)textFieldShouldReturn:(UITextField *)textField {
    if ([textField isKindOfClass:[SOTextField class]]) {
        UITextField *nextField = [(SOTextField *)textField nextField];

        if (nextField) {
            dispatch_async(dispatch_get_current_queue(), ^{
                [nextField becomeFirstResponder];
            });
        }
        else {
            [textField resignFirstResponder];
        }
    }

    return YES;
}

En IB, cambie sus UITextFields para usar la SOTextFieldclase. A continuación, también en IB, establezca el delegado para cada uno de los 'SOTextFields' en 'Propietario del archivo' (que es justo donde puso el código para el método delegado: textFieldShouldReturn). La belleza de este diseño es que ahora puede simplemente hacer clic derecho en cualquier campo de texto y asignar la salida nextField al siguiente SOTextFieldobjeto que desea que sea el siguiente respondedor.

Asignar nextField en IB

Además, puedes hacer cosas interesantes como repetir los campos de texto para que después de que el último pierda el foco, el primero vuelva a recibir el foco.

Esto se puede ampliar fácilmente para asignar automáticamente el returnKeyTypede SOTextFielda UIReturnKeyNextsi hay un nextField asignado: una cosa menos que se puede configurar manualmente.

memmons avatar May 04 '2011 21:05 memmons