iOS版:同时规模和3D旋转动画(iOS: Simultaneous scale and 3D ro

2019-07-17 13:20发布

我做了一个视频展示了我想要完成的动画: 这是。

注意视频显示,因为它会从侧面可以看到的动作。 相机图标代表了用户的POV。 它基本上完成虽然尺度变换,以同时独立两步3D旋转沿X轴发生的Z轴之间的转换的模拟。

看起来和听起来很简单,不是吗? 错误。 这里是理想的代码,它不工作:

[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
  • 缓和效果应该是如图所示,特别是在旋转

当然,如果一个解决方案来了,需要一些这样的变化,我可以适应。

在此先感谢您的帮助。 如果您需要澄清,就问吧。

Answer 1:

没有第一动画被取消你不能动画相同的属性。 您应该下降到使用的Core Animation,要么做两个动画或一个关键帧动画。

两个转变动画

通过创建一个缩放动画(其中,如果你愿意,你可以做的是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)

透视

在这两种情况下,我通过设置在动画视图的superlayer的sublayerTransform做的透视(假设仅存在一个子视图与变换那里)

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


Answer 2:

我找到了一种方法,但它更像是一个黑客。 请执行下列操作 -

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

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



文章来源: iOS: Simultaneous scale and 3D rotation animation