CABasicAnimation旋转返回到原始位置 [英] CABasicAnimation rotate returns to original position

查看:138
本文介绍了CABasicAnimation旋转返回到原始位置的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用CABasicAnimation旋转CALayer并且工作正常。问题是,当我尝试旋转同一层时,它会在旋转之前返回到原始位置。我的预期输出是,对于下一次轮换,它应该从它结束的地方开始。这是我的代码:

i'm rotating a CALayer using CABasicAnimation and works fine. The problem is, when I try to rotate the same layer, it returns back to its original position before it will rotate. My expected output is that, for the next rotation, it should start from where it has ended. Here's my code:

CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"transform.rotation"];
animation.fromValue         = 0;
animation.toValue           = [NSNumber numberWithFloat:3.0];
animation.duration          = 3.0;
animation.timingFunction    = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
animation.removedOnCompletion = NO;
animation.fillMode          = kCAFillModeForwards;
animation.autoreverses      = NO;
[calayer addAnimation:animation forKey:@"rotate"];

我的代码上有什么遗漏?谢谢

Is there anything missing on my code? thanks

推荐答案

发生的事情是您在表示层中看到了动画。但是,这不会更新图层的实际位置。所以,一旦动画结束,你就会看到图层,因为它没有改变。

What's happening is that you're seeing the animation in the presentation layer. However, that doesn't update the actual position of your layer. So, once the animation finishes, you see the layer as it was because it hasn't changed.

真的值得阅读核心动画渲染架构。否则这可能会让人感到困惑。

It's really worth reading the "Core Animation Rendering Architecture". Otherwise this can be very confusing.

要修复它,请将代理设置为 CABasicAnimation ,如下所示:

To fix it, set a delegate to your CABasicAnimation as follows:

[animation setDelegate:self];

然后,创建一个方法来设置动画完成时所需的目标属性。现在,这是令人困惑的部分。您应该在 animationDidStart 而不是 animationDidStop 上执行此操作。否则,表示层动画将完成,当你在原始位置看到 calayer 然后它跳转 - 没有动画 - 到目标位置时你会得到一个闪烁。尝试使用 animationDidStop ,你会明白我的意思。

Then, create a method to set your target properties that you want when the animation completes. Now, here's the confusing part. You should do this on animationDidStart not animationDidStop. Otherwise, the presentation layer animation will finish, and you'll get a flicker as you see the calayer in the original position then it jumps - without animation - to the target position. Try it with animationDidStop and you'll see what I mean.

我希望这不会太混乱!

- (void)animationDidStart:(CAAnimation *)theAnimation
{
    [calayer setWhateverPropertiesExpected];
}

编辑:

我后来发现Apple建议采用更好的方法来做到这一点。

I later discovered that Apple recommend a much better way to do this.

Oleg Begemann 在他的博客文章中对正确的技术有很好的描述使用显式CAAnimations时阻止图层回弹到原始值

基本上你所做的就是在开始动画之前,你要注意图层的当前状态值,即原始值:

Basically what you do is before you start the animation, you take a note of the layer's current value, i.e., the original value:

// Save the original value
CGFloat originalY = layer.position.y;

接下来,在图层模型上设置 toValue 。因此,图层模型具有您要执行的任何动画的最终值

Next, set the toValue on the layer's model. Therefore the layer model has the final value of whatever animation you are about to do:

// Change the model value
layer.position = CGPointMake(layer.position.x, 300.0);

然后,您将动画设置为动画 fromValue 为原始动画你在上面提到的价值:

Then, you set the animation up with the animation fromValue being that original value that you noted above:

CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"position.y"];

// Now specify the fromValue for the animation because
// the current model value is already the correct toValue
animation.fromValue = @(originalY);
animation.duration = 1.0;

// Use the name of the animated property as key
// to override the implicit animation
[layer addAnimation:animation forKey:@"position"];

请注意,上面编辑的代码是从Ole Begemann的博客中复制/粘贴的清晰度

Note that code in edit above was copy/pasted from Ole Begemann's blog for clarity

这篇关于CABasicAnimation旋转返回到原始位置的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆