Horizontal horizontal liso con CATransform3DMakeRotation

He configurado la siguiente animation para rotar entre vistas de diferentes tamaños. El punto medio de la animation parece tener un parpadeo cuando se ve la nueva vista más alta. ¿Hay algo que pueda hacer para suavizar la transición?

newView.layer.transform = CATransform3DMakeRotation(M_PI_2, 0.0, 1.0, 0.0); [UIView animateWithDuration:0.5 delay:0 options:UIViewAnimationOptionCurveLinear animations:^{oldView.layer.transform = CATransform3DMakeRotation(M_PI_2, 0.0, -1.0, 0.0);} completion:^(BOOL finished) { [oldView removeFromSuperview]; [UIView animateWithDuration:0.5 delay:0 options:UIViewAnimationOptionCurveLinear animations:^{newView.layer.transform = CATransform3DMakeRotation(M_PI_2, 0.0, 0.0, 0.0);} completion:nil]; }]; 

Esto funcionó gracias a este hilo, así que pensé que compartiría mi transformada 3D desde la matriz m34.

introduzca la descripción de la imagen aquí

  UIView *toView = // show this UIView *fromView = // hide this one // set up from CATransform3D fromViewRotationPerspectiveTrans = CATransform3DIdentity; fromViewRotationPerspectiveTrans.m34 = -0.003; // 3D ish effect fromViewRotationPerspectiveTrans = CATransform3DRotate(fromViewRotationPerspectiveTrans, M_PI_2, 0.0f, -1.0f, 0.0f); // set up to CATransform3D toViewRotationPerspectiveTrans = CATransform3DIdentity; toViewRotationPerspectiveTrans.m34 = -0.003; toViewRotationPerspectiveTrans = CATransform3DRotate(toViewRotationPerspectiveTrans, M_PI_2, 0.0f, 1.0f, 0.0f); toView.layer.transform = toViewRotationPerspectiveTrans; [UIView animateWithDuration:1.0 delay:0 options:UIViewAnimationOptionCurveLinear animations:^{fromView.layer.transform = fromViewRotationPerspectiveTrans; } completion:^(BOOL finished) { [fromView removeFromSuperview]; [UIView animateWithDuration:1.0 delay:0 options:UIViewAnimationOptionCurveLinear animations:^{toView.layer.transform = CATransform3DMakeRotation(M_PI_2, 0.0, 0.0, 0.0);} completion:nil]; }]; 

Estaba a medio path, pero la pieza faltante, que establece el valor de celda m34 de la matriz de transformación , hizo el truco.

Como señaló David, su código no tiene sentido como está escrito. Está configurando la rotation final de su nuevoView en una rotation alnetworkingedor de nada, lo que PROBABLEMENTE será equivalente a la matriz de identidad, pero no estoy seguro.

Esto es lo que intentaría (estoy cansado, así que veamos si puedo explicar esto de manera coherente …)

Anime el oldView de 0 a pi / 2 como paso de animation 1. Establezca el nuevoView a -pi / 2 antes de comenzar la segunda animation (girado 90 grados hacia el otro lado).

En el método de finalización, quite la vista anterior e inicie una animation para volver a poner a cero la rotation de la nueva vista. Eso hará que la nueva vista parezca que sigue girando en un giro de 180 grados.

Esta es la parte difícil. Calcule la diferencia de tamaño (horizontal y vertical) entre las vistas antiguas y las nuevas. Agregue (concatene) una transformación de escala junto con la rotation, de modo que cuando finalice la primera parte de la rotation, se escala al promedio del tamaño antiguo y nuevo. El pseudocódigo podría verse así:

 //Scale to apply to oldView for the first part of the animation: scale height = ((oldView.size.height+newView.size.height)/2) / oldView.size.height scale width = ((oldView.size.width+newView.size.width)/2) / oldView.size.width /* Before beginning the second part of the animation, rotate newView to -pi/2, and scale it by an amount that makes it the same size that oldView will be at the end of the first animation (the average of the sizes of both views) */ newView scale height = ((oldView.size.height+newView.size.height)/2) / newView.size.height newView scale width = ((oldView.size.width+newView.size.width)/2) / newView.size.width 

en el bloque de finalización, elimine oldView de su supervisión y anime newView a la transformación de identidad.

Si mi enfoque es correcto, al final de la primera animation, oldView debería escalarse a un tamaño a medio path entre los tamaños de oldView y newView.

La segunda animation, activada en el bloque de finalización de la primera, comenzará con newView siendo del mismo tamaño que scaled a oldView al final de la primera animation. La segunda animation terminará con la nueva vista girando en su lugar y networkinguciéndose a su tamaño original.