在 CAAnimationGroup 完成后无缝更新图层的视觉 属性 值?
Seamlessly updating a layer's visual property values after a `CAAnimationGroup` completes?
我正在尝试为比例设置动画 然后 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
为某些属性设置动画,在末尾移除动画,而不让旧值窥视一帧?
我之前给过 the long version of this answer。这里没有理由重复详细的解释。
但简短的回答是您看到图层的隐式动画被应用到显式动画之上。我之前写过a detailed explanation about implicit and explicit animations and multiple simulations animation,如果你想了解更多的话。
如"the long answer"所述。您的问题的解决方案是更新属性,但暂时禁用隐式动画,以便它们不会应用在您的显式动画之上:
[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
我正在尝试为比例设置动画 然后 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
为某些属性设置动画,在末尾移除动画,而不让旧值窥视一帧?
我之前给过 the long version of this answer。这里没有理由重复详细的解释。
但简短的回答是您看到图层的隐式动画被应用到显式动画之上。我之前写过a detailed explanation about implicit and explicit animations and multiple simulations animation,如果你想了解更多的话。
如"the long answer"所述。您的问题的解决方案是更新属性,但暂时禁用隐式动画,以便它们不会应用在您的显式动画之上:
[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