3

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

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

    }];
4

3 回答 3

7

多亏了这个线程才能使这个工作,所以我想我会使用 m34 矩阵分享我的 to-from 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];

                     }];
于 2014-05-19T02:48:04.890 回答
1

我到了一半,但是缺少的部分,设置转换矩阵的 m34 单元格值,起到了作用。

于 2012-10-02T12:25:39.867 回答
-1

正如大卫指出的那样,您的代码编写起来没有意义。您将 newView 的最终旋转设置为围绕任何内容旋转,这可能等同于单位矩阵,但我不确定。

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

作为动画步骤 1,将 oldView 从 0 设置为 pi/2。在开始第二个动画之前将 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 缩放到的大小相同。第二个动画将以新视图旋转到位并缩小到其原始大小而结束。

于 2012-09-27T01:55:34.410 回答