CABasicAnimation旋转返回原始位置

nez*_*reh 3 rotation calayer cabasicanimation ios

我正在使用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"];
Run Code Online (Sandbox Code Playgroud)

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

Max*_*eod 16

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

这真的值得阅读"核心动画渲染架构".否则这可能会令人困惑.

要修复它,请CABasicAnimation按如下方式将委托设置为:

[animation setDelegate:self];

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

我希望这不会太混乱!

- (void)animationDidStart:(CAAnimation *)theAnimation
{
    [calayer setWhateverPropertiesExpected];
}
Run Code Online (Sandbox Code Playgroud)

编辑:

我后来发现苹果推荐一种更好的方法来做到这一点.

Oleg Begemann在他的博客文章中使用明确的CAAnimations预防图层恢复原始值时对正确的技术进行了很好的描述

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

// Save the original value
CGFloat originalY = layer.position.y;
Run Code Online (Sandbox Code Playgroud)

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

// Change the model value
layer.position = CGPointMake(layer.position.x, 300.0);
Run Code Online (Sandbox Code Playgroud)

然后,设置动画,动画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"];
Run Code Online (Sandbox Code Playgroud)

请注意,为了清楚起见,上面编辑的代码是从Ole Begemann的博客中复制/粘贴的