CABasicAnimation使用总结

  • 格式:pdf
  • 大小:135.02 KB
  • 文档页数:4

CABasicAnimation使⽤总结

CABasicAnimation使⽤总结

实例化

使⽤⽅法animationWithKeyPath:对 CABasicAnimation进⾏实例化,并指定Layer的属性作为关键路径进⾏注册。

//围绕y轴旋转

CABasicAnimation *transformAnima = [CABasicAnimation animationWithKeyPath:@"transform.rotation.y"];

设定动画

设定动画的属性和说明

属性说明

duration动画的时长

repeatCount重复的次数。不停重复设置为 HUGE_VALF

repeatDuration设置动画的时间。在该时间内动画⼀直执⾏,不计次数。

beginTime指定动画开始的时间。从开始延迟⼏秒的话,设置为【CACurrentMediaTime() + 秒数】 的⽅式

timingFunction设置动画的速度变化

autoreverses动画结束时是否执⾏逆动画

fromValue所改变属性的起始值

toValue所改变属性的结束时的值

byValue所改变属性相同起始值的改变量

transformAnima.fromValue = @(M_PI_2);

transformAnima.toValue = @(M_PI);

transformAnima.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];

transformAnima.autoreverses = YES;

transformAnima.repeatCount = HUGE_VALF;

transformAnima.beginTime = CACurrentMediaTime() + 2;

防⽌动画结束后回到初始状态

只需设置removedOnCompletion、fillMode两个属性就可以了。

transformAnima.removedOnCompletion = NO;

transformAnima.fillMode = kCAFillModeForwards;

解释:为什么动画结束后返回原状态?

⾸先我们需要搞明⽩⼀点的是,layer动画运⾏的过程是怎样的?其实在我们给⼀个视图添加layer动画时,真正移动并不是我们的视图本⾝,⽽

是 presentation layer 的⼀个缓存。动画开始时 presentation layer开始移动,原始layer隐藏,动画结束时,presentation layer从屏幕上移除,

原始layer显⽰。这就解释了为什么我们的视图在动画结束后⼜回到了原来的状态,因为它根本就没动过。

这个同样也可以解释为什么在动画移动过程中,我们为何不能对其进⾏任何操作。

所以在我们完成layer动画之后,最好将我们的layer属性设置为我们最终状态的属性,然后将presentation layer 移除掉。

添加动画

[self.imageView.layer addAnimation:transformAnima forKey:@"A"];需要注意的两点

⼀个 CABasicAniamtion 的实例对象只是⼀个数据模型,和他绑定到哪⼀个layer上是没有关系的

⽅法addAnimation:forKey:是将 CABasicAniamtion 对象进⾏了 copy 操作的。所以在将其添加到⼀个layer上之后,我们还是将其再次添加到

另⼀个layer上的。

fillMode属性的理解

该属性定义了你的动画在开始和结束时的动作。默认值是 kCAFillModeRemoved。取值的解释

kCAFillModeRemoved 设置为该值,动画将在设置的 beginTime 开始执⾏(如没有设置beginTime属性,则动画⽴即执⾏),动画执⾏

完成后将会layer的改变恢复原状。

kCAFillModeForwards 设置为该值,动画即使之后layer的状态将保持在动画的最后⼀帧,⽽removedOnCompletion的默认属性值是YES,所以为了使动画结束之后layer保持结束状态,应将removedOnCompletion设置为NO。

kCAFillModeBackwards 设置为该值,将会⽴即执⾏动画的第⼀帧,不论是否设置了 beginTime属性。观察发现,设置该值,刚开始视图不见,还不知道应⽤在哪⾥。

kCAFillModeBoth 该值是 kCAFillModeForwards 和 kCAFillModeBackwards的组合状态

Animation Easing的使⽤

也即是属性timingFunction值的设定,有种⽅式来获取属性值

(1)使⽤⽅法functionWithName:这种⽅式很简单,这⾥只是简单说明⼀下取值的含义:

kCAMediaTimingFunctionLinear 传这个值,在整个动画时间内动画都是以⼀个相同的速度来改变。也就是匀速运动。

kCAMediaTimingFunctionEaseIn 使⽤该值,动画开始时会较慢,之后动画会加速。

kCAMediaTimingFunctionEaseOut 使⽤该值,动画在开始时会较快,之后动画速度减慢。

kCAMediaTimingFunctionEaseInEaseOut 使⽤该值,动画在开始和结束时速度较慢,中间时间段内速度较快。

(2)使⽤⽅法functionWithControlPoints: : : :实现,这个之后再说,占个坑先。其他的⼀些设置属性

repeatCount 设置动画的执⾏次数

autoreverses 默认值为 NO,将其设置为 YES

speed 改变动画的速度 可以直接设置动画上的speed属性,这样只有这个动画速度。

animation.speed = 2;

或者在layer上设置speed属性,这样在该视图上的所有动画都提速,该视图上的所有⼦视图上的动画也会提速。

speed两点需注意的:

(1) 如果设置动画时间为4s,speed设置为2,则动画只需2s即可执⾏完。

(2)如果同时设置了动画的speed和layer 的speed,则实际的speed为两者相乘。使⽤总结

在动画执⾏完成之后,最好还是将动画移除掉。也就是尽量不要设置removedOnCompletion属性为NO

fillMode尽量取默认值就好了,不要去设置它的值。只有在极个别的情况下我们会修改它的值,以后会说到,这⾥先占个坑。

解决有时视图会闪动⼀下的问题,我们可以将layer的属性值设置为我们的动画最后要达到的值,然后再给我们的视图添加layer动画。

例⼦(移动动画实现)

直接上代码

CABasicAnimation *positionAnima = [CABasicAnimation animationWithKeyPath:@"position.y"];

positionAnima.duration = 0.8;

positionAnima.fromValue = @(self.imageView.center.y);

positionAnima.toValue = @(self.imageView.center.y-30);

positionAnima.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];

positionAnima.repeatCount = HUGE_VALF;

positionAnima.repeatDuration = 2;

positionAnima.removedOnCompletion = NO;

positionAnima.fillMode = kCAFillModeForwards;

[self.imageView.layer addAnimation:positionAnima forKey:@"AnimationMoveY"];

组合动画的实现

CABasicAnimation *positionAnima = [CABasicAnimation animationWithKeyPath:@"position.y"];

positionAnima.fromValue = @(self.imageView.center.y);

positionAnima.toValue = @(self.imageView.center.y-30);

positionAnima.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];

CABasicAnimation *transformAnima = [CABasicAnimation animationWithKeyPath:@"transform.rotation.y"];

transformAnima.fromValue = @(0);

transformAnima.toValue = @(M_PI);

transformAnima.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];

CAAnimationGroup *animaGroup = [CAAnimationGroup animation];

animaGroup.duration = 2.0f;animaGroup.fillMode = kCAFillModeForwards;

animaGroup.removedOnCompletion = NO;

animaGroup.animations = @[positionAnima,transformAnima];

[self.imageView.layer addAnimation:animaGroup forKey:@"Animation"];

动画开始和结束时的事件

为了获取动画的开始和结束事件,需要实现协议

positionAnima.delegate = self;

代理⽅法实现

//动画开始时

- (void)animationDidStart:(CAAnimation *)anim

{

NSLog(@"开始了");

}

//动画结束时

- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag

{

//⽅法中的flag参数表明了动画是⾃然结束还是被打断,⽐如调⽤了removeAnimationForKey:⽅法或removeAnimationForKey⽅法,flag为NO,如果是正常结束,flag为YES。

NSLog(@"结束了");

}

其实⽐较重要的是有多个动画的时候如何在代理⽅法中区分不同的动画

两种⽅式

⽅式⼀:

如果我们添加动画的视图是全局变量,可使⽤该⽅法。