CAAnimationGroup直接继承自CAAnimation。它自身一个非常简单的动画类,只扩展了一个属性NSArray<CAAnimation *> *animations用来存储子动画。CAAnimationGroup可以将多个子动画并发运行在自己的时间空间中。
这篇文章重点讨论beginTime、duration、fillMode、removedOnCompletion等属性同时在CAAnimationGroup和子动画中同时设置时,所产生的效果。
这里先说一下结论:
- CAAnimationGroup的beginTime用来控制整个动画组的开始时间可以设置为CACurrentMediaTime()+N,N代表动画组的开始时间从单签时间延迟N秒。子动画中的beginTime用来设置子动画在CAAnimationGroup时间空间中开始时间向后的延时时间,它可以设置为N。例如CAAnimationGroup的beginTime=CACurrentMediaTime()+2,子动画的设置为beginTime = 1. 则表示子动画在CAAnimationGroup动画开始后1秒后才进行子动画的运行,即可以近似理解为是CACurrentMediaTime()+3。
- CAAnimationGroup的duration控制整个动画组的动画运行时间,子动画的duration空值子动画的动画运行时间。当CAAnimationGroup的动画时间运行时间结束时,子动画未运行完成则子动画会被剪切。例如CAAnimationGroup的duration = gDuration,子动画的beginTime = cBeginTime。则子动画会运行到gDuration-cBeginTime时,动画结束。
- 当需要动画在结束是保持动画的最终状态,一般会设置fillMode =kCAFillModeForwards、removedOnCompletion=NO。那到底该设置CAAnimationGroup的相关属性还是子动画的相关属性呢?特别是子动画和CAAnimationGroup的运行时间不一致时该如何设置?
结论如下:
3.1 子动画的fillMode、kCAFillModeForwards控制子动画,在动画组时间内动画的最终状态。如果子动画提前于CAAnimationGroup运行结束,则子动画会在CAAnimationGroup运行的剩余时间内保持子动画的最终状态,当CAAnimationGroup运行完成后子动画回复到原始状态(CAAnimationGroup 未设置fillMode =kCAFillModeForwards、removedOnCompletion=NO的情况)
3.2 CAAnimationGroup的fillMode、kCAFillModeForwards控制CAAnimationGroup在运行结束时,是否保持子动画当前的动画状态(有可能尚未完成,取当前呈现树的状态)。
[self.view.layer addSublayer:self.layer];
CABasicAnimation *aniPosition = [CABasicAnimation animation];
//在动画组运行结束后子动画仍然没有运行完成,因此最终子动画会在其开始2秒时停住。并保持最终状态
aniPosition.beginTime = 1;
aniPosition.duration = 3;
aniPosition.keyPath = @"position";
aniPosition.fromValue = [NSValue valueWithCGPoint:CGPointMake(25, self.view.center.y)];
aniPosition.toValue = [NSValue valueWithCGPoint:CGPointMake([UIScreen mainScreen].bounds.size.width-25, self.view.center.y)];
aniPosition.fillMode = kCAFillModeBoth;
aniPosition.removedOnCompletion = NO;
CABasicAnimation *colorBasic = [CABasicAnimation animation];
colorBasic.duration = 3;
colorBasic.keyPath = @"backgroundColor";
colorBasic.fromValue = (__bridge id _Nullable)([UIColor redColor].CGColor);
colorBasic.toValue = (__bridge id _Nullable)([UIColor blackColor].CGColor);
colorBasic.fillMode = kCAFillModeBoth;
colorBasic.removedOnCompletion = NO;
CAAnimationGroup *group = [CAAnimationGroup animation];
group.animations = @[aniPosition, colorBasic];
group.duration = 3;
group.beginTime = CACurrentMediaTime()+3;
group.fillMode = kCAFillModeBoth;
group.removedOnCompletion = NO;
[self.layer addAnimation:group forKey:@""];