UIKit mensajes UIKeyboardWillShowNotification
cuando muestra el teclado, y UIKeyboardWillHideNotification
cuando se oculta el teclado. Estas notificaciones contienen todo lo que necesita para animar correctamente su UITextField
.
Digamos que su UITextField
se encuentra en una propiedad llamada myTextField
.
En primer lugar, debe registrarse para recibir notificaciones en algún lugar. Donde se registra depende de qué objeto es responsable de mover myTextField
. En mi proyecto, supervista del campo es responsable, y puesto que cargo mi interfaz de usuario a partir de una semilla, lo hago en el supervista awakeFromNib
:
- (void)awakeFromNib
{
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHideOrShow:) name:UIKeyboardWillHideNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHideOrShow:) name:UIKeyboardWillShowNotification object:nil];
}
Si utiliza un UIViewController
para mover el campo alrededor, es probable que quiero hacerlo en viewWillAppear:animated:
.
Debe anular el registro en su dealloc
o viewWillDisappear:animated:
:
- (void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
Por supuesto, el truco está en el método keyboardWillHideOrShow:
. En primer lugar puedo extraer los parámetros de animación de la notificación:
- (void)keyboardWillHideOrShow:(NSNotification *)note
{
NSDictionary *userInfo = note.userInfo;
NSTimeInterval duration = [[userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue];
UIViewAnimationCurve curve = [[userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey] intValue];
CGRect keyboardFrame = [[userInfo objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];
El keyboardFrame
es en el sistema de coordenadas global. Necesito convertir la trama al mismo sistema de coordenadas que myTextField.frame
y myTextField.frame
está en el sistema de coordenadas de myTextField.superview
:
CGRect keyboardFrameForTextField = [self.myTextField.superview convertRect:keyboardFrame fromView:nil];
A continuación, calcular el marco que quiero myTextField
para mover a. El borde inferior de la nueva trama debe ser igual a la borde superior del bastidor del teclado:
CGRect newTextFieldFrame = self.myTextField.frame;
newTextFieldFrame.origin.y = keyboardFrameForTextField.origin.y - newTextFieldFrame.size.height;
Finalmente, animo myTextField
a su nuevo marco, usando los mismos parámetros de animación que el teclado está usando:
[UIView animateWithDuration:duration delay:0 options:UIViewAnimationOptionBeginFromCurrentState | curve animations:^{
self.myTextField.frame = newTextFieldFrame;
} completion:nil];
}
Aquí se puso juntos:
- (void)keyboardWillHideOrShow:(NSNotification *)note
{
NSDictionary *userInfo = note.userInfo;
NSTimeInterval duration = [[userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue];
UIViewAnimationCurve curve = [[userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey] intValue];
CGRect keyboardFrame = [[userInfo objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];
CGRect keyboardFrameForTextField = [self.myTextField.superview convertRect:keyboardFrame fromView:nil];
CGRect newTextFieldFrame = self.myTextField.frame;
newTextFieldFrame.origin.y = keyboardFrameForTextField.origin.y - newTextFieldFrame.size.height;
[UIView animateWithDuration:duration delay:0 options:UIViewAnimationOptionBeginFromCurrentState | curve animations:^{
self.myTextField.frame = newTextFieldFrame;
} completion:nil];
}
Gracias. Gracias. Gracias. Gracias. Con una pequeña modificación, lo tengo funcionando y se ve súper resbaladizo. – iosfreak
@rob mayoff el problema es cuando tengo un 'UITabBar'. Cuando el teclado ocultará las diapositivas 'UITextField' debajo de' UITabBar'. ¿Por qué? –
Si tiene una barra de pestañas, cuando el teclado se esconde, necesita calcular 'newTextFieldFrame' basado en el marco de la barra de pestañas en lugar del marco del teclado. –