我正在使用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"];
我的代码上有什么遗漏?感谢
答案 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