CoreAnimation-CAKeyframeAnimation

453 阅读2分钟

我们通常在下面两个场景下使用CAKeyframeAnimation

一、想象下面的需求,先放大1.2倍,再缩小到0.8,再放大到1.5倍,甚至要求每一段变化的时间都是可控的,那这个时候我们使用CAKeyframeAnimation就可以很方便的实现

创建动画

CAKeyframeAnimation *scaleAnimation = [CAKeyframeAnimation animationWithKeyPath:@"transform.scale"];

设置放大的倍数,是一个数组

scaleAnimation.values = @[@(1.2),@(0.8),@(1.5)];

可以通过keyTimes属性来控制每一段的时间变化,keyTimes属性指定的是当前状态节点到初始状态节点的时间占动画总时长的比例。若果不设置keyTimes则匀速播放

scaleAnimation.keyTimes = @[@0.f, @0.16f, @0.28f];

然后设置动画时长并添加动画

我们并不是只能用来做缩放效果,还可以针对旋转,透明度的不停变化等等

二、CAKeyframeAnimation还经常用在当我们希望一个UIView或CALayer围绕着一个路径不停移动的时候,例如我们希望实现一辆小车围绕指定圆不停的跑,这个时候我们也可以用CAKeyframeAnimation加贝塞尔曲线来实现

首先,用UIBezierPath画一个圆并使用CAShapeLayer把它显示在视图上

UIBezierPath *path = [UIBezierPath bezierPath];

[path addArcWithCenter:CGPointMake(self.view.frame.size.width / 2, self.view.frame.size.height / 2) radius:50 startAngle:0 endAngle:M_PI * 2 clockwise:YES];

CAShapeLayer *shaperLayer = [CAShapeLayer layer];

shaperLayer.lineWidth = 5;

shaperLayer.fillColor = nil;

shaperLayer.strokeColor = [UIColor redColor].CGColor;

shaperLayer.path = path.CGPath;

[self.view.layer addSublayer:shaperLayer];

接下来把我们的小汽车画出来

CALayer *carLayer = [CALayer layer];

carLayer.frame = CGRectMake(self.view.frame.size.width / 2 - 18, self.view.frame.size.height / 2 - 50 - 30, 36, 36);

carLayer.contents = (id)[UIImage imageNamed:@"car"].CGImage;

[self.view.layer addSublayer:carLayer];

因为我们的小汽车不是围绕当前圆的中心进行移动的这样看起来会比较奇怪,应该是围绕外侧稍微大点的圆进行移动,所以我们需要画一个稍微大点的圆

UIBezierPath *bigPath = [UIBezierPath bezierPath];

[bigPath addArcWithCenter:CGPointMake(self.view.frame.size.width / 2, self.view.frame.size.height / 2) radius:62 startAngle:-M_PI / 2 endAngle:M_PI * 3 / 2 clockwise:YES];
   

最后给汽车添加关键帧动画,让动画的path等于我们刚刚创建的bigPath,并且让我们的汽车进行一个旋转

CAKeyframeAnimation *anim = [CAKeyframeAnimation animation];

 anim.keyPath = @"position";

 anim.path = bigPath.CGPath;

 anim.duration = 4.0;

 anim.repeatCount = MAXFLOAT;

 CABasicAnimation *basicAnim = [CABasicAnimation animation];

 basicAnim.keyPath = @"transform.rotation.z";

 basicAnim.toValue = @(M_PI * 2);

 basicAnim.duration = 4.0;

 basicAnim.repeatCount = MAXFLOAT;

 CAAnimationGroup *animationGroup = [CAAnimationGroup animation];

 animationGroup.animations = @[anim, basicAnim];

 animationGroup.duration = 4.0;

 animationGroup.repeatCount = MAXFLOAT;

 [carLayer addAnimation:animationGroup forKey:**nil**];