12

Actualmente tengo un UITextField en la parte superior de un teclado. Cuando lo tocas, debe permanecer sobre el teclado y subir suavemente. No sé la duración exacta y el tipo de animación del teclado, por lo que es muy accidentado. Aquí es lo que tengo:¿Mantener el objeto sobre el teclado en caso de becomeFirstResponder o resignFirstResponder?

[theTextView resignFirstResponder]; 
[UIView beginAnimations:nil context:NULL]; 
[UIView setAnimationDelegate:self]; 
[UIView setAnimationDuration:0.25]; 
[UIView setAnimationCurve:UIViewAnimationCurveLinear]; 
// Frame changes go here (move down 216px) 
[UIView commitAnimations]; 

[theTextView becomeFirstResponder]; 
[UIView beginAnimations:nil context:NULL]; 
[UIView setAnimationDelegate:self]; 
[UIView setAnimationDuration:0.25]; 
[UIView setAnimationCurve:UIViewAnimationCurveLinear]; 
// Frame changes go here (move up 216px) 
[UIView commitAnimations]; 

Si alguien ha hecho algo como esto antes, me gustaría conocer la configuración que utilizó para hacer la animación suave y hacer que parezca que la barra es "pegado" a la parte superior de el teclado.

Respuesta

44

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]; 
} 
+1

Gracias. Gracias. Gracias. Gracias. Con una pequeña modificación, lo tengo funcionando y se ve súper resbaladizo. – iosfreak

+0

@rob mayoff el problema es cuando tengo un 'UITabBar'. Cuando el teclado ocultará las diapositivas 'UITextField' debajo de' UITabBar'. ¿Por qué? –

+0

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. –

0

para hacer que el UITextField se acople al teclado (con animación), debe hacer cálculos de desplazamiento y aplicar cambios de desplazamiento en la vista de desplazamiento (suponiendo que UITextField se coloca en UIScrollView) utilizando el método setContentOffset:animation:.

+0

No está en ScrollView. Un scrollView ni siquiera existe, es una UITableView. – iosfreak

+2

@ phpnerd211: UITableView es una subclase de UIScrollView. – Andrew

5

Fije su campo de texto (o una vista que sostiene el campo de texto) como el inputAccessoryView del campo que estás editando Luego se adjuntará automáticamente a la parte superior del teclado y se animará de forma adecuada.

Cuestiones relacionadas