Cómo navegar a través de campos de texto (botones Siguiente/Listo)
¿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.
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:
- Todos los "tabbable"
UITextField
están en la misma vista principal. - 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!
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
UITextField
yUITextView
, 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 IBOutlet
propiedad 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 SOTextField
clase. 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 SOTextField
objeto que desea que sea el siguiente respondedor.
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 returnKeyType
de SOTextField
a UIReturnKeyNext
si hay un nextField asignado: una cosa menos que se puede configurar manualmente.