在“CAAnimationGroup”完成后无缝更新图层的可视属性值?

时间:2015-04-01 10:08:17

标签: ios cocoa-touch core-animation

我试图为比例设置动画然后 CALayer的不透明度,如下所示:

CABasicAnimation *scaleUp = [CABasicAnimation animationWithKeyPath:@"transform"];
scaleUp.fromValue = [NSValue valueWithCATransform3D:self.timerProgressLayer.transform];
scaleUp.toValue = [NSValue valueWithCATransform3D:CATransform3DMakeScale(1.0, 1.0, 1.0)];
scaleUp.duration = 0.25;
scaleUp.fillMode = kCAFillModeForwards;

CABasicAnimation *fadeOut = [CABasicAnimation animationWithKeyPath:@"opacity"];
fadeOut.fromValue = @(1.0);
fadeOut.toValue = @(0.0);
fadeOut.beginTime = 0.3;
fadeOut.duration = 0.25;
fadeOut.fillMode = kCAFillModeForwards;

CAAnimationGroup *group = [CAAnimationGroup animation];
group.animations = @[scaleUp, fadeOut];
group.removedOnCompletion = YES;
group.duration = fadeOut.beginTime + fadeOut.duration;

[self.timerProgressLayer addAnimation:group forKey:@"trigger"];

这很简单,动画本身也很好用。但是,在动画结束时,它被移除,值将恢复为开头的值。为了解决这个问题,我在addAnimation:调用后立即手动设置属性:

self.timerProgressLayer.opacity = 0.0;
self.timerProgressLayer.transform = CATransform3DMakeScale(1.0, 1.0, 1.0);

但是,这些调用会覆盖我的动画,图层会淡出并立即缩放。如果我使用动画的delegate[CATransaction setCompletionBlock:]来设置动画结束时的属性,很多时候(但不是100%的时间),单帧旧状态在动画结束和正在设置的属性之间通过。

如何使用CAAnimationGroup为某些属性设置动画,最后删除动画而不使用旧值查看帧?

1 个答案:

答案 0 :(得分:3)

我之前已经给过the long version of this answer。这里没有理由重复详细说明。

但简短的回答是,您正在看到图层的隐式动画应用于显式动画之上。我之前写过a detailed explanation about implicit and explicit animations and multiple simulations animation,如果你想了解更多相关内容。


如#34;长答案"所述。问题的解决方案是更新属性,但暂时禁用隐式动画,以便它们不会应用于显式动画:

[CATransaction begin];
[CATransaction setDisableActions:YES]; // actions are disabled for now

self.timerProgressLayer.opacity = 0.0;
self.timerProgressLayer.transform = CATransform3DMakeScale(1.0, 1.0, 1.0);

[CATransaction commit];                // until here