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的中间)
简单地设置fillMode
和removedOnCompletion
没有为我工作。 我通过将下面的所有属性设置为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.scale
, transform.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) }