Core Animation注意事项

最近在公司项目中有很多动效处理,在做一个先上下后左右进行阻尼运动时,本人是通过Core Animation中的CASpringAnimation进行实现。

实现思路:将整个动画拆分为两块:先做上下阻尼运动,再做左右阻尼运动。

iOS 9中Apple自带了CASpringAnimation,因此添加两个连续的阻尼动画,就可以实现想要的效果。先上代码:

- (void)shakeAnimationForView {

CASpringAnimation *springAnimation = [CASpringAnimation animationWithKeyPath:@"position.y"];

springAnimation.damping = 1;

springAnimation.stiffness = 300;

springAnimation.mass = 1;

springAnimation.initialVelocity = 0;

springAnimation.fromValue = @(self.locusAnimationView.center.y);

springAnimation.toValue = @(self.locusAnimationView.center.y - 5);

springAnimation.repeatCount = 1;

springAnimation.duration = 0.5;

springAnimation.delegate = self;

springAnimation.autoreverses = YES;

[self.locusAnimationView.layer addAnimation:springAnimation forKey:@"positionY"];

}

以上是做上下阻尼运动,So nice! 运行起来正是需要的结果。然后实现CAAnimationDelegate,在第一个动画完成后,开始左右阻尼运动:

#pragma mark - CAAnimationDelegate

- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag

{

if ([anim isEqual:[self.locusAnimationView.layer animationForKey:@"positionX"]]) {

[self shakeAnimationForView:self.locusAnimationView];

return;

}

[self.locusAnimationView.layer removeAllAnimations];

if (flag) {

CASpringAnimation *springAnimation = [CASpringAnimation animationWithKeyPath:@"position.x"];

springAnimation.damping = 1;

springAnimation.stiffness = 300;

springAnimation.mass = 1;

springAnimation.initialVelocity = 0;

springAnimation.fromValue = @(self.locusAnimationView.center.x);

springAnimation.toValue = @(self.locusAnimationView.center.x + 5);

springAnimation.duration = 0.5;

springAnimation.repeatCount = 1;

springAnimation.delegate = self;

springAnimation.autoreverses = YES;

[self.locusAnimationView.layer addAnimation:springAnimation forKey:@"positionX"];

}

}

恩,就这样,大功告成,我们先Run起来看看是不是跟预期的效果一致。我擦,什么鬼!做了一次上下阻尼后一直重复左右阻尼运动。这跟我们要的效果完全不一样啊。然后断点调试,发现在CAAnimationDelegate中通过[self.locusAnimationView.layer animationForKey:@"positionX"]获取不到CAAnimation的对象,因此

if ([anim isEqual:[self.locusAnimationView.layer animationForKey:@"positionX"]]) {

[self shakeAnimationForView:self.locusAnimationView];

return;

}

该判断一直跳过,所以重复进行左右阻尼运动。那到底是什么原因造成通过animationForKey找不到对应的Animation对象呢?

经过半天折腾,在stackover上终于找到了答案。

对于Core Aniamtion中有个属性removedOnCompletion,默认为YES,表示当动画完成时把这个动画移除,因此通过上述方式一直找不到对应的CAAnimation。现在我们把这个属性添加到我们以上两段代码中并设为NO,表示动画结束后不移除,再run下,结果正是我们想要的。

你可能感兴趣的:(Core Animation注意事项)