¿Cómo imitar la animación del teclado en iOS 7 para agregar el botón "Hecho" al teclado numérico?
objective-c animation (6)
Apple está utilizando algunas animaciones no documentadas con el valor 7 en iOS 7.
Sin embargo, la declaración de UIViewAnimationCurve
define valores para 0 a 3
typedef enum {
UIViewAnimationCurveEaseInOut, // 0
UIViewAnimationCurveEaseIn,
UIViewAnimationCurveEaseOut,
UIViewAnimationCurveLinear // 3
} UIViewAnimationCurve;
UIViewAnimationOptions
que necesita para las animaciones basadas en bloques se define como
enum {
// ...
UIViewAnimationOptionCurveEaseInOut = 0 << 16,
UIViewAnimationOptionCurveEaseIn = 1 << 16,
UIViewAnimationOptionCurveEaseOut = 2 << 16,
UIViewAnimationOptionCurveLinear = 3 << 16,
UIViewAnimationOptionTransitionNone = 0 << 20,
// ...
};
Parece que Apple reserva 4 bits para la curva de animación (20 - 16 = 4) que permite valores de 0 a 15 (por lo que probablemente haya más valores no documentados).
Con este conocimiento, puede simplemente transformar una UIViewAnimationCurve
en UIViewAnimationOptions
desplazándola alrededor de 16 bits. En tu ejemplo, esto significa:
options:[[note.userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey] intValue] << 16
He estado haciendo algo como esto para imitar la animación del teclado en la versión anterior de iOS.
CGRect keyboardBeginFrame;
[[note.userInfo objectForKey:UIKeyboardFrameBeginUserInfoKey] getValue:&keyboardBeginFrame];
self.doneKeyboardButton.frame = CGRectMake(0, (keyboardBeginFrame.origin.y + keyboardBeginFrame.size.height) - 53, 106, 53);
[[[[UIApplication sharedApplication] windows] lastObject] addSubview:self.doneKeyboardButton];
CGPoint newCenter = CGPointMake(self.doneKeyboardButton.superview.frame.origin.x + self.doneKeyboardButton.frame.size.width/2,
self.doneKeyboardButton.superview.frame.size.height - self.doneKeyboardButton.frame.size.height/2);
[UIView animateWithDuration:[[note.userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] floatValue]-.02
delay:.0
options:[[note.userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey] intValue]
animations:^{
self.contentView.frame = CGRectOffset(self.contentView.frame, 0, -TextFieldViewMovement);
self.doneKeyboardButton.center = newCenter;
}
completion:nil];
Sin embargo, esto ha dejado de funcionar en iOS7. Parece que los valores devueltos ya no son exactamente correctos, y el botón Hecho ya no imita exactamente la animación de visualización del teclado.
En iOS 7, el teclado usa una nueva curva de animación no documentada. Mientras que algunos han notado que el uso de un valor no documentado para la opción de animación funciona, prefiero usar lo siguiente:
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:[notification.userInfo[UIKeyboardAnimationDurationUserInfoKey] doubleValue]];
[UIView setAnimationCurve:[notification.userInfo[UIKeyboardAnimationCurveUserInfoKey] unsignedIntegerValue]];
[UIView setAnimationBeginsFromCurrentState:YES];
// work
[UIView commitAnimations];
Si bien las animaciones basadas en bloques son la recomendación, la curva de animación devuelta desde la notificación del teclado es una UIViewAnimationCurve
, mientras que la opción que necesitaría pasar a las animaciones basadas en bloques es una UIViewAnimationOptions
. El uso de los métodos de animación UIView tradicionales le permite canalizar el valor directamente en. Lo más importante, esto utilizará la nueva curva de animación no documentada (valor entero de 7) y hará que la animación coincida con el teclado . Y funcionará igual de bien en iOS 6 y 7.
Esto funciona bien para mí ... La duración se detecta cuando se muestra el teclado. Sé que codificar de forma rígida las opciones significa que podría romperse en el futuro, pero funciona para 7 y 8. Eso es suficiente para nosotros por ahora ...
[UIView animateWithDuration:self.animationDuration
delay:0.0
options:UIViewAnimationOptionCurveEaseInOut
animations:^{
[self.view layoutIfNeeded]; completion:^(BOOL finished) {
if (finished)
{
if (completion)
completion();
}
}];
Puede usar el bloque animateWithDuration
y establecer la curva dentro de él. Está limpio y funciona bien.
UIViewAnimationCurve curve = [[notification.userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey] integerValue];
double duration = [[notification.userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue];
[UIView animateWithDuration:duration
delay:0
options:UIViewAnimationOptionBeginFromCurrentState
animations:^{
[UIView setAnimationCurve:curve];
/* ANIMATION HERE */
// don''t forget layoutIfNeeded if you use autolayout
}
completion:nil];
Feliz codificación!
ACTUALIZAR
Puede usar una categoría simple de UIViewController escrita por mí https://github.com/Just-/UIViewController-KeyboardAnimation
Si desea agregar el botón dentro de una barra de herramientas (de forma similar a como lo hace Safari), puede usar la propiedad inputAccessoryView
(tanto UITextField
como UITextView
tienen) y ahorrarse todos los problemas. Esta joya escondida es poco conocida, estoy contento de haberme topado con ella.
Funciona tanto en iOS 6 como en iOS 7, lo estoy usando en mi aplicación Routie .
Tuve el mismo problema y logré que la animación funcionara con los siguientes parámetros para iOS 7:
[UIView animateWithDuration:0.5
delay:0
usingSpringWithDamping:500.0f
initialSpringVelocity:0.0f
options:UIViewAnimationOptionCurveLinear
animations:animBlock
completion:completionBlock];
EDITAR: estos valores se obtuvieron a través de la depuración y pueden cambiar con nuevas versiones de iOS. La respuesta de @DavidBeck me funciona en iOS 7 también, así que la voy a vincular aquí.