CABasicAnimation旋转返回原始位置

时间:2011-10-07 05:55:20

标签: ios calayer rotation cabasicanimation

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

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

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

2 个答案:

答案 0 :(得分:16)

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

真的值得一读"Core Animation Rendering Architecture"。否则这可能会令人困惑。

要解决此问题,请按以下方式将代理人设置为CABasicAnimation

[animation setDelegate:self];

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

我希望这不会太混乱!

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

编辑:

我后来发现Apple建议采用更好的方法来实现这一目标。

Oleg Begemann 在他的博文Prevent Layers from Snapping Back to Original Values When Using Explicit CAAnimations

中对正确的技术有很好的描述

基本上你所做的就是在开始动画之前,记下图层的当前值,即原始值:

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

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

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

然后,您设置动画,动画 fromValue 是您在上面提到的原始值:

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的博客中复制/粘贴

答案 1 :(得分:1)

如果您希望动画从结束位置开始,请将fromValue属性设置为CALayer的当前旋转。

获取该值很棘手,但这篇SO帖子向您展示了如何:https://stackoverflow.com/a/6706604/1072846