animation完成后,CABasicAnimation重置为初始值

我正在旋转CALayer并在animation完成后试图将其停止在最终位置。

但animation完成后重置到其初始位置。

(xcode docs明确说animation不会更新属性的值。)

任何build议如何实现这一点。

编辑 :这是答案,这是我的答案和克里希南的组合。

cabasicanimation.fillMode = kCAFillModeForwards; cabasicanimation.removedOnCompletion = NO; 

默认值是kCAFillModeRemoved 。 (你看到的是重置行为。)

removedOnCompletion的问题是UI元素不允许用户交互。

我的技巧是在animation中设置FROM值,在对象上设置TO值。 animation会在开始之前自动填充TO值,当它被移除时会使对象保持正确的状态。

 // fade in CABasicAnimation *alphaAnimation = [CABasicAnimation animationWithKeyPath: @"opacity"]; alphaAnimation.fillMode = kCAFillModeForwards; alphaAnimation.fromValue = NUM_FLOAT(0); self.view.layer.opacity = 1; [self.view.layer addAnimation: alphaAnimation forKey: @"fade"]; 

设置以下属性:

 animationObject.removedOnCompletion = NO; 

只是把它放在你的代码里面

 CAAnimationGroup *theGroup = [CAAnimationGroup animation]; theGroup.fillMode = kCAFillModeForwards; theGroup.removedOnCompletion = NO; 

您可以简单地将CABasicAnimation的键设置为当您将其添加到图层时的位置。 通过这样做,它将覆盖在运行循环中当前传递位置上执行的隐式animation。

 CGFloat yOffset = 30; CGPoint endPosition = CGPointMake(someLayer.position.x,someLayer.position.y + yOffset); someLayer.position = endPosition; // Implicit animation for position CABasicAnimation * animation =[CABasicAnimation animationWithKeyPath:@"position.y"]; animation.fromValue = @(someLayer.position.y); animation.toValue = @(someLayer.position.y + yOffset); [someLayer addAnimation:animation forKey:@"position"]; // The explicit animation 'animation' override implicit animation 

你可以有更多的信息在2011年的苹果WWDCvideo会议421 – 核心animation基础(video的中间)

简单地设置fillModeremovedOnCompletion没有为我工作。 我通过将下面的所有属性设置为CABasicAnimation对象来解决问题:

 CABasicAnimation* ba = [CABasicAnimation animationWithKeyPath:@"transform"]; ba.duration = 0.38f; ba.fillMode = kCAFillModeForwards; ba.removedOnCompletion = NO; ba.autoreverses = NO; ba.repeatCount = 0; ba.toValue = [NSValue valueWithCATransform3D:CATransform3DMakeScale(0.85f, 0.85f, 1.0f)]; [myView.layer addAnimation:ba forKey:nil]; 

此代码将myView转换为其大小的85%(第三维不变)。

CALayer有一个模型层和一个表示层。 在animation中,表示层独立于模型更新。 animation完成后,表示层将使用模型中的值进行更新。 如果你想避免在animation结束后出现震动,那么关键是保持两层同步。

如果您知道最终值,则可以直接设置模型。

 self.view.layer.opacity = 1; 

但是如果你有一个不知道结束位置的animation(例如,用户可以暂停然后反转的缓慢淡出),那么你可以直接查询表示层来查找当前值,然后更新模型。

 NSNumber *opacity = [self.layer.presentationLayer valueForKeyPath:@"opacity"]; [self.layer setValue:opacity forKeyPath:@"opacity"]; 

从表示层拉取值对于缩放或旋转关键path也特别有用。 (如transform.scaletransform.rotation

@莱斯利·戈德温的回答不太好,“self.view.layer.opacity = 1;” 立即完成(大约需要一秒),如果你有疑问,请修正alphaAnimation.duration到10.0。 你必须删除这一行。

所以,当您将fillMode修复为kCAFillModeForwards,并将removedOnCompletion修改为NO时,您将让animation保留在图层中。 如果您修复animation委托,并尝试如下所示:

 - (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag { [theLayer removeAllAnimations]; } 

在你执行这一行时,图层立即恢复。 这是我们想要避免的。

您必须修复图层属性,然后从中删除animation。 尝试这个:

 - (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag { if([anim isKindOfClass:[CABasicAnimation class] ]) // check, because of the cast { CALayer *theLayer = 0; if(anim==[_b1 animationForKey:@"opacity"]) theLayer = _b1; // I have two layers else if(anim==[_b2 animationForKey:@"opacity"]) theLayer = _b2; if(theLayer) { CGFloat toValue = [((CABasicAnimation*)anim).toValue floatValue]; [theLayer setOpacity:toValue]; [theLayer removeAllAnimations]; } } } 

这工作:

 let animation = CABasicAnimation(keyPath: "opacity") animation.fromValue = 0 animation.toValue = 1 animation.duration = 0.3 someLayer.opacity = 1 // important, this is the state you want visible after the animation finishes. someLayer.addAnimation(animation, forKey: "myAnimation") 

核心animation在animation期间在正常层上显示“表示层”。 所以当animation结束和表示层消失时,将不透明度(或其他)设置为您想要查看的内容。 添加animation之前,先在线上执行此操作,以避免完成时的闪烁。

如果您想要延迟,请执行以下操作:

 let animation = CABasicAnimation(keyPath: "opacity") animation.fromValue = 0 animation.toValue = 1 animation.duration = 0.3 animation.beginTime = someLayer.convertTime(CACurrentMediaTime(), fromLayer: nil) + 1 animation.fillMode = kCAFillModeBackwards // So the opacity is 0 while the animation waits to start. someLayer.opacity = 1 // <- important, this is the state you want visible after the animation finishes. someLayer.addAnimation(animation, forKey: "myAnimation") 

最后,如果使用“removedOnCompletion = false”,它会泄漏CAAnimations直到图层最终被丢弃 – 避免。

看来,removedOnCompletion标志设置为false,fillMode设置为kCAFillModeForwards也不适用于我。

在图层上应用新的animation之后,animation对象将重置为其初始状态,然后从该状态进行animation处理。 另外需要做的是在设置新的animation之前,根据表示层的属性设置模型图层的所需属性,如下所示:

 someLayer.path = ((CAShapeLayer *)[someLayer presentationLayer]).path; [someLayer addAnimation:someAnimation forKey:@"someAnimation"]; 

不使用removedOnCompletion

你可以试试这个技巧:

 self.animateOnX(item: shapeLayer) func animateOnX(item:CAShapeLayer) { let endPostion = CGPoint(x: 200, y: 0) let pathAnimation = CABasicAnimation(keyPath: "position") // pathAnimation.duration = 20 pathAnimation.fromValue = CGPoint(x: 0, y: 0)//comment this line and notice the difference pathAnimation.toValue = endPostion pathAnimation.fillMode = kCAFillModeBoth item.position = endPostion//prevent the CABasicAnimation from resetting item's position when the animation finishes item.add(pathAnimation, forKey: nil) }