使用CATransform3DMakeRotation平滑水平翻转

我已设置以下动画以在不同大小的视图之间旋转。 随着新的,更高的视图进入视野,动画的中点似乎有一个闪烁。 我能做些什么来平滑过渡。

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

由于这个线程得到了这个工作,所以我想我会使用m34矩阵分享我的来自3D变换。

在此处输入图像描述

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

我在那里,但缺少的部分,设置转换矩阵的m34单元格值 ,做了伎俩。

正如大卫指出的那样,你的代码没有意义。 你将newView的最终旋转设置为无旋转,这可能会等同于单位矩阵,但我不确定。

这是我会尝试的(我很累,所以让我们看看我是否可以连贯地解释这个……)

将oldView从0设置为pi / 2动画作为动画步骤1.在开始第二个动画之前将newView设置为-pi / 2(从另一个方向旋转90度。)

在完成方法中,删除旧视图并启动动画以将新视图的旋转设置回零。 这将使新视图看起来像是在180度翻转中继续翻转。

这是棘手的部分。 计算旧视图和新视图之间的大小(水平和垂直)差异。 添加(连接)缩放变换以及旋转,以便在旋转的第一部分完成时,将其缩放到旧尺寸和新尺寸的平均值。 伪代码可能如下所示:

 //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 

在完成块中,从其超级视图中删除oldView,并将newView动画回标识转换。

如果我的方法是正确的,在第一个动画结束时,应将oldView缩放到oldView和newView大小之间的大小。

在第一个动画结束时,第二个动画将在第一个完成时触发,其中newView的大小与第一个动画结束时的oldView相同。 第二个动画将以新视图旋转到位并缩小到原始大小而结束。