2011-10-07 279 views
3

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

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

我的代码有什么缺失?谢谢

回答

16

发生什么事情是,你看到表示层中的动画。但是,这并不会更新图层的实际位置。所以,一旦动画完成,您会看到该图层,因为它没有改变。

确实值得一读"Core Animation Rendering Architecture"。否则,这可能会非常混乱。

[animation setDelegate:self];

然后,创建设置动画完成时,你希望你的目标属性的方法:

为了解决这个问题,如下设置委托给你的CABasicAnimation。现在,这是令人困惑的部分。您应该在animationDidStart而不是animationDidStop上执行此操作。否则,表示层动画将完成,当您看到calayer处于原始位置时,您将看到闪烁,然后它会跳跃(无动画)到目标位置。试试animationDidStop,你会明白我的意思。

我希望这不是太混乱!

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

编辑:

我后来发现,苹果推荐一个更好的方法来做到这一点。

奥列格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"]; 

注以上编辑的代码是复制/奥莱Begemann的博客粘贴为清楚起见

+0

你将如何与诸如transform.rotation.y关键路径做到这一点? – Msencenb

+0

对我来说,为动画设置一个键并不能代替隐式动画,所以我不得不使用[这个答案](https://stackoverflow.com/a/2244734/865175)。 –

1

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

获得该值是棘手的,但这SO后告诉您如何:https://stackoverflow.com/a/6706604/1072846

+0

我认为这比另一个建议使用[animationDidStart:]的答案更合适,这是海报想要的东西 –