iOS: escala simultánea y animation de rotation 3D

Hice un video demostrando la animation que estoy tratando de lograr: aquí está.

Observe que el video ilustra la acción como se vería desde el lateral. El ícono de la camera representa el POV del usuario. Básicamente es una simulación de una traducción entre el eje Z realizada mediante una transformación de escala, con una rotation 3D simultánea e independiente de dos pasos que ocurre a lo largo del eje X.

Parece y parece lo suficientemente simple, ¿verdad? Incorrecto. Aquí está el código ideal, que no funciona:

[UIView animateWithDuration:0.4 delay:0.0 options:UIViewAnimationOptionCurveEaseInOut animations:^{ view.transform = CGAffineTransformMakeScale(1.0, 1.0); } completion:^(BOOL finished) {}]; [UIView animateWithDuration:0.2 delay:0.0 options:UIViewAnimationOptionCurveEaseInOut animations:^{ CATransform3D rotation = CATransform3DIdentity; rotation.m34 = 1.0 / - 1800; rotation = CATransform3DRotate(rotation, - 20 * M_PI / 180.0f, 1, 0, 0); view.layer.transform = rotation; } completion:^(BOOL finished) { [UIView animateWithDuration:0.2 delay:0.0 options:UIViewAnimationOptionCurveEaseInOut animations:^{ view.layer.transform = CATransform3DIdentity; } completion:^(BOOL finished) {}]; }]; 

Resulta que, si lo hace, la rotation 3D se ignorará por completo. He intentado una serie de otros enfoques, y todos han fallado.

Algunos requisitos:

  • La escala debería ser preferiblemente una CGAffineTransform
  • Las medidas deben ser como se ilustra, especialmente en la rotation

Por supuesto, si surge una solución que requiere que algunos de estos cambien, podría adaptarme.

Gracias de antemano por cualquier ayuda. Si necesita una aclaración, pregunte.

No puede animar la misma propiedad sin cancelar la primera animation. Debería usar Down Core Animation y hacer dos animaciones o una animation de fotogtwigs key.

Dos animaciones de transformación

Al crear una animation para escalar (que podría hacer como traducción z si lo desea) y otra para rotar, dándoles routes key muy específicas, no se cancelarán entre sí.

 CABasicAnimation *scale = [CABasicAnimation animationWithKeyPath:@"transform.scale"]; scale.fromValue = @0.75; // Your from value (not obvious from the question) scale.toValue = @1.0; scale.duration = 0.4; scale.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]; CAKeyframeAnimation *rotate = [CAKeyframeAnimation animationWithKeyPath:@"transform.rotation.x"]; rotate.values = @[@0.0, @(- 20 * M_PI / 180.0f), @0.0]; rotate.duration = 0.4; rotate.timingFunctions = @[[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut], [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]]; [view.layer addAnimation:scale forKey:@"move forward by scaling"]; [view.layer addAnimation:rotate forKey:@"rotate back and forth"]; view.transform = CGAffineTransformIdentity; // Set end value (animation won't apply the value to the model) 

Una sola animation de fotogtwigs key

Dado que tiene tres fotogtwigs key muy buenos, el código para animar entre los tres fotogtwigs key sería fácil de leer y comprender. Es posible que pierda parte del control si desea cambiar el time de la escala separada de la rotation.

 CATransform3D firstFrame = CATransform3DMakeScale(0.75, 0.75, 1.0); CATransform3D secondFrame = CATransform3DMakeScale(0.875, 0.875, 1.0); // halfway to 1.0 from 0.75 secondFrame = CATransform3DRotate(secondFrame, -20.0*M_PI/180.0, 1.0, 0.0, 0.0); CATransform3D lastFrame = CATransform3DIdentity; CAKeyframeAnimation *scaleAndRotate = [CAKeyframeAnimation animationWithKeyPath:@"transform"]; scaleAndRotate.values = @[[NSValue valueWithCATransform3D:firstFrame], [NSValue valueWithCATransform3D:secondFrame], [NSValue valueWithCATransform3D:lastFrame] ]; scaleAndRotate.duration = 1.0; scaleAndRotate.timingFunctions = @[[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut], [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]]; [view.layer addAnimation:scaleAndRotate forKey:@"entire animation"]; view.transform = CGAffineTransformIdentity; // Set end value (animation won't apply the value to the model) 

Perspectiva

En ambos casos, hice la perspectiva al configurar la subcapaTransform en la superestructura de la vista animada (suponiendo que solo hay una subvista con una transformación allí)

 CATransform3D perspective = CATransform3DIdentity; perspective.m34 = 1.0 / - 1800.0; view.superview.layer.sublayerTransform = perspective; 

Encontré una forma pero es más como un truco. Haz lo siguiente –

1) crear una vista con background transparente – (esta vista se traducirá) 2) crear una subvista de 1) – (esta vista girará).

Ahora use crear dos transformaciones, una transformación de escala para la vista 1) y una transformación de rottaión para la vista 2) y aplicarlas simultáneamente.