核心动画 – 未调用animationDidStop

那里。

在iOS应用程序中,Core动画回调不起作用。

- (void)startAnim { CABasicAnimation* anim = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"]; anim.fromValue = startAngle; anim.toValue = endAngle; anim.duration = 2; anim.delegate = self; [self.target addAnimation:anim forKey:nil]; // self.target is CALayer instance, it's sublayer of Custom UIView } - (void)animationDidStop:(CAAnimation *)theAnimation finished:(BOOL)flag { [self.target setValue:@(endAngle) forKeyPath:@"transform.rotation.z"]; } 

但是从未调用过animationDidStop。 如果我像下面那样更改代码,则调用完成阻止。

 - (void)startAnim { CABasicAnimation* anim = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"]; anim.fromValue = startAngle; anim.toValue = endAngle; anim.duration = 2; anim.delegate = self; [CATransaction begin]; [CATransaction setCompletionBlock:^{ [self.target setValue:@(endAngle) forKeyPath:@"transform.rotation.z"]; }]; [self.target addAnimation:anim forKey:nil]; [CATransaction commit]; } 

但我不想使用CATransaction。 为什么不调用animationDidStop?

更新:有一种方法可以将最终值设置为as

 - (void)startAnim { CABasicAnimation* anim = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"]; anim.fromValue = startAngle; anim.toValue = endAngle; anim.duration = 2; anim.delegate = self; [self.target setValue:@(endAngle) forKeyPath:@"transform.rotation.z"]; [self.target addAnimation:anim forKey:nil]; } 

但是最终的作业应该在动画结束时完成。 因为图层有多个动态动画,所以我不知道最终值。

我找到了没有调用animationDidStop的原因。

因为动画是在其他线程的循环中添加的,

所以我修复如下。

 - (void)startAnim { dispatch_async(dispatch_get_main_queue(), ^{ CABasicAnimation* anim = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"]; anim.fromValue = startAngle; anim.toValue = endAngle; anim.duration = 2; anim.delegate = self; [self.target addAnimation:anim forKey:nil]; }); } 

去年我使用UIView的动画而不是CABasicAnimation,但如果我的记忆没有失败,你必须设置endAngle来添加动画,所以试试这个:

 - (void)startAnim { CABasicAnimation* anim = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"]; anim.fromValue = startAngle; anim.toValue = endAngle; anim.duration = 2; anim.delegate = self; [self.target setValue:@(endAngle) forKeyPath:@"transform.rotation.z"]; [self.target addAnimation:anim forKey:nil]; } 

UPD:

你正在设置anim.toValue = endAngle; 在开始动画之前,动画完成后结束值不会改变。 无论如何,你可以在animationDidStop再次设置它

 - (void)startAnim { CABasicAnimation* anim = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"]; anim.fromValue = startAngle; anim.toValue = endAngle; anim.duration = 2; anim.delegate = self; intermediateAngle = endAngle; [self.target setValue:@(endAngle) forKeyPath:@"transform.rotation.z"]; [self.target addAnimation:anim forKey:nil]; } - (void)animationDidStop:(CAAnimation *)theAnimation finished:(BOOL)flag { if (intermediateAngle != endAngle) { startAngle = intermediateAngle; [self startAnim]; // or just [self.target setValue:@(endAngle) forKeyPath:@"transform.rotation.z"]; } } 

对我而言,听起来你不希望动画重置它的位置,这很简单,并且在设置动画时用几行代码实现。

它可以很容易地放在你的代码中,如:

anim.fillMode = kCAFillModeForwards; anim.removedOnCompletion = NO;

这意味着当你的动画完成时它将保持在最后,任何进一步的动画将来自该状态。