使用CATransform3DMakeRotation平滑水平翻转

时间:2012-09-24 12:38:39

标签: ios core-animation

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

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

    }];

3 个答案:

答案 0 :(得分:7)

感谢这个线程的工作,所以我想我会使用m34矩阵分享我的来自3D转换。

enter image description here

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

                     }];

答案 1 :(得分:1)

我已经到了一半,但是设置m34 cell value of the transformation matrix的缺失部分就是这样做的。

答案 2 :(得分:-1)

大卫指出,你的代码没有意义。你将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

在完成块中,从它的superview中删除oldView, 并将newView动画回标识转换。

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

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