【问题标题】:iOS: Simultaneous scale and 3D rotation animationiOS:同时缩放和 3D 旋转动画
【发布时间】:2012-12-24 04:10:39
【问题描述】:

我制作了一个视频来展示我想要完成的动画:Here it is.

请注意,视频说明了从侧面看到的动作。相机图标代表用户的 POV。它基本上是通过比例变换完成 Z 轴之间平移的模拟,同时沿 X 轴发生独立的两步 3D 旋转。

看起来和听起来都很简单,对吧?错误的。这是理想的代码,它不起作用:

[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) {}];
}];

事实证明,如果您这样做,3D 旋转将被完全忽略。我尝试了许多其他方法,但都失败了。

一些要求:

  • 比例最好是CGAffineTransform
  • 缓动应如图所示,尤其是轮换时

当然,如果出现需要更改其中一些内容的解决方案,我可以适应。

提前感谢您的帮助。如果您需要澄清,请询问。

【问题讨论】:

  • 我无法让您的视频正常播放(不过,通过 iPhone 浏览)。动画开始时视图的变换应该是什么?
  • 非常说明性的视频(而且看起来很漂亮)。你是怎么做到的?
  • @jrturton 该视图最初的比例小于 1。
  • @DavidRönnqvist 谢谢!我使用带有动作功能的 Keynote。如果你想剖析它,这里是 .key 文件:cl.ly/LmIa

标签: ios uiview core-animation cgaffinetransform catransform3d


【解决方案1】:

如果不取消第一个动画,您将无法为同一属性设置动画。您应该选择使用核心动画并制作两个动画或一个关键帧动画。

两个变换动画

通过创建一个用于缩放的动画(如果需要,您可以将其作为 z 平移)和一个用于旋转的动画,为它们提供非常具体的关键路径,它们不会相互取消。

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)

单个关键帧动画

由于您拥有三个非常好的关键帧,因此在三个关键帧之间进行动画处理的代码将很容易阅读和理解。如果您想将缩放的时间与旋转的时间分开更改,您可能会失去一些控制。

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)

视角

在这两种情况下,我都是通过在动画视图的超层上设置 sublayerTransform 来进行透视的(假设那里只有一个带有变换的子视图)

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

【讨论】:

  • 这看起来很棒。我明天试试,让你知道结果如何。非常感谢,节日快乐!
  • 我等不及了,从技术上讲,明天就在这里了,所以我试了一下,效果很好!我选择了第一个,因为它使两个转换之间的计时功能分开。非常感谢!
【解决方案2】:

我找到了一种方法,但它更像是一种 hack。执行以下操作 -

1)创建一个具有透明背景的视图 - (此视图将翻译) 2)创建一个子视图1) - (这个视图将旋转)。

现在使用创建两个变换,视图 1) 的缩放变换和视图 2) 的旋转变换并同时应用它们。

【讨论】:

    猜你喜欢
    • 2018-04-24
    • 2023-02-20
    • 1970-01-01
    • 2011-12-27
    • 2012-03-22
    • 1970-01-01
    • 1970-01-01
    • 2023-03-23
    • 2021-12-20
    相关资源
    最近更新 更多