ios objective-c animation ios8 cgaffinetransform

La animación de CGAffineTransform en iOS8 se ve diferente que en iOS7



objective-c animation (6)

CGAffineTransformIdentity se comporta de manera diferente en ios7 y ios8. Esto tiene que ver con el diseño automático y las clases de tamaño. La solución es eliminar las restricciones que entren en conflicto con la animación en ios7.

// solve the constraint-animation problem if(NSFoundationVersionNumber <= NSFoundationVersionNumber_iOS_7_1) { // iOS7 remove constraints that conflict with animation if (self.centerYAlignment != nil) { self.view.removeConstraint(self.centerYAlignment) //is an IBOutlet } } else { // iOS8 constraint animations are fine }

Estoy tratando de encontrar una razón por la cual la animación de la propiedad de transformación UIView ve diferente en iOS 8 que en iOS 6/7.

Para un ejemplo simple, antes de iOS 8:

myView.transform = CGAffineTransformRotate(CGAffineTransformIdentity, 1.57); [UIView animateWithDuration:5 animations:^{ myView.transform = CGAffineTransformTranslate(plane.transform, 100, 0); }];

da el resultado esperado, "myView" se gira 90 grados y se mueve hacia abajo, pero en iOS8, cuando la traducción está animada, comienza en un punto en el que no pude encontrar una explicación (lo que rompe la animación).

¿Alguien sabe la explicación para ello? ¡Gracias por adelantado!


Creo que la razón es el error de iOS8, pero uso CAAnimation en su lugar, y funciona como se espera en iOS8.


Esto no está del todo relacionado, pero estaba luchando con que CGAffineTransformScale no funcionara en absoluto en iOS7 en una animación bastante complicada. Resulta que mi problema era que iOS7 no puede calcular CGAffineTransformScale con CGAffineTransformRotate al mismo tiempo. En iOS7, la última llamada de animación que haces es la única que se anima, por lo que solo se estaba produciendo la rotación. Este error se corrige en iOS8.

Mi solución es simplificar mi animación para iOS7, solo activando las cosas de lujo en iOS8:

//Pre-animation setup: CGFloat radians = (M_PI/180) * (-15); //Get a human-readable number in degrees self.badgeImage.alpha = 0; //Start the image as invisible self.badgeImage.transform = CGAffineTransformScale(self.badgeImage.transform, 1.5, 1.5); //Start the image as scaled bigger than normal if(NSFoundationVersionNumber > NSFoundationVersionNumber_iOS_7_1) { //See below. We will not be rotating the image in iOS7 self.badgeImage.transform = CGAffineTransformRotate(self.badgeImage.transform, radians); //Rotate the image if iOS8 } //Animation Pieces: //Fade in [UIView animateWithDuration: 0.5 delay:0 options:0 animations:^{ self.badgeImage.alpha = 1.0f; //Return image to opaque } completion:NULL]; //Scale with bounce [UIView animateWithDuration: 1.1 delay:0 usingSpringWithDamping:0.3 //Not as good as Android''s bounce interpolator, but I''ll take it initialSpringVelocity:-1.0f //A negative velocity here makes the animation appear more like gravity than spring options:0 animations:^{ self.badgeImage.transform = CGAffineTransformScale(self.badgeImage.transform, 0.67, 0.67); //Return image to its original size. These arguments are relative to its current scale. } completion:NULL]; //Rotation if(NSFoundationVersionNumber > NSFoundationVersionNumber_iOS_7_1) { //This second animation call negates the first one on iOS7, so remove it. [UIView animateWithDuration: 0.9 delay:0 options:UIViewAnimationOptionCurveEaseOut animations:^{ self.badgeImage.transform = CGAffineTransformRotate(self.badgeImage.transform, (radians * -1)); //Rotate the image back to its original orientation if iOS8 } completion:NULL]; }

Por supuesto, aún puede combinar múltiples efectos en iOS7 si usa la función CGAffineTransformMakeScale() que se utiliza de forma confusa. Por ejemplo, en la configuración de pre-animación, puede establecer una rotación Y una escala, luego configurar la llamada CGAffineTransformMakeScale(1,1) para restablecer la imagen a sus métricas originales (los argumentos de MakeScale son específicos, no relativos, incluso más ¡confuso!). Esto no siempre es preferible, como en mi ejemplo anterior donde "rebotar" la animación también haría rebotar la rotación.


Estoy de acuerdo con Pbk en que tiene que ver con clases de tamaño en io8. Los controladores uiview deben ser redimensionados con uitraitcollections dependiendo de la orientación del dispositivo. De lo contrario, obtiene un controlador uiview en modo vertical, mientras el teléfono está en modo horizontal, cuando intenta girarlo. Así que los pasos correctos son rotar Y anular uitraitcollections


También estoy experimentando el mismo problema con la escala. Supongo que podría ser lo mismo con la rotación. ¿Podrías intentar esto?

myView.transform = CGAffineTransformConcat(myView.transform , CGAffineTransformMakeRotate(1.57)); [UIView animateWithDuration:5 animations:^{ myView.transform = CGAffineTransformTranslate(plane.transform, 100, 0); }];

Tal vez también sea necesario usar CGAffineTransformMakeTranslate y CGAffineTransformConcat que tampoco estoy seguro.

La peor parte de esto es: tendría que hacer si / else en las versiones de iOS, porque esto se vería raro en iOS 7. Espero que Apple lo arregle antes o con el lanzamiento de iOS 8.


También tuve problemas con la transformación de rotación desigual en iOS7. Resuelto esto anidando mi vista girada dentro de un contenedor y centrando la vista girada dentro.