iOS 核心动画是基于CALayer层的动画,UIView动画是系统对核心动画的封装,核心动画相对UIView来说实现步骤更多,但可以实现的效果也更多,核心动画在后台处理不会阻塞主线程。在实际开发中,使用UIView动画不好实现的可以采用核心动画来实现,但优先使用UIView动画。可以依照下面画出的类结构图来系统地学习核心动画的知识。
类的说明:
(实际使用的是最下面的4个类)
CAAnimation
是动画类的基类,是一个抽象类。CAMediaTimingFunction
是用来动画时间曲线的类,一般使用系统提供的几个值:kCAMediaTimingFunctionLinear
kCAMediaTimingFunctionEaseIn
kCAMediaTimingFunctionEaseOut
kCAMediaTimingFunctionEaseInEaseOut
kCAMediaTimingFunctionDefault
CAAnimationGroup
是组合动画,可将其他3个动画类的对象添加进到这个对象里面,组合起来动画CAPropertyAniamtion
是抽象类,是对图层属性作动画的类,具体的动画由它的两个子类去实现CABasicAnimation
用来做单个关键帧(single-keyframe animation)动画,图层从fromValue
动画到toValue
CAKeyframeAnimation
用来做关键帧动画,通过Values
来决定经过几个点,keyTimes
来确定经过的两个点之间的时间; 还可以通过path
来设置图层的动画的轨迹 。CABasicAnimation可看做是最多只有2个关键帧的CAKeyframeAnimation。CATransition
称为转场动画或过渡动画。由type属性来确定转场动画类型。
动画效果列举
核心动画的知识
CALayer与UIView及自定义CALayer的知识点
一、自定义CALayer
方法一:新建CALayer的子类,重写drawInContext:
方法. 在实际应用时添加到view的layer上,调用layer的setNeedsDispaly方法即可
方法二:创建CALayer对象添加到view的layer上时,设置CALayer对象的代理,然后在代理方法drawLayer:InContext:
在这里方法里面绘制图层显示的内容。
UIView对象显示的视图由它的CAlayer决定,这个layer的代理就是view对象
二、UIView的显示过程
- 准备一个图形上下文GraphicsContext
- view的layer调用它的代理:view的
drawLayer:InContext:
方法 -
drawLayer:InContext:
方法里面会调用view的drawRect:
方法 -
drawRect:
方法调用完后,图层绘制完毕,系统拷贝到屏幕上显示
核心动画的实现步骤:
1> 根据需要选择好上面类结构图中最底部的4个类创建动画对象,设置动画的key
2> 设置好动画属性,添加到layer上
3> 动画对象需要设置下面两个属性
// 这两个属性配合使用,使动画完毕之后保持动画完的状态,否则会回到最初的状态上。
// removedOnCompletion = NO; 这个可以避免程序进入后台再进入前台时动画停止的bug
anim.fillMode = kCAFillModeForwards;
anim.removedOnCompletion = NO;
一个使用例子
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"];
可动画的keypath表格
UIView动画的API结构与CoreAniamation对比
对应一:动画实现不带block
// UIView动画方法
[UIView beginAnimations:nil context:nil];
// ......具体动画
[UIView commitAnimations];
// CoreAniamation中与上面对应的是
[CATransaction begin];
// ......具体动画
[CATransaction commit];
对应二:基本动画带block
[UIView animateWithDuration: delay: options: animations: completion:];
// 上面方法对应着CoreAniamation里面的CABasicAnimation和CAAnimationGroup
CABasicAnimation *transformAnima = [CABasicAnimation animationWithKeyPath:@"transform.rotation.y"];
// ......具体动画属性设置
CAAnimationGroup *animaGroup = [CAAnimationGroup animation];
animaGroup.duration = 2.0f;
animaGroup.fillMode = kCAFillModeForwards;
animaGroup.removedOnCompletion = NO;
animaGroup.animations = @[transformAnima];
对应三:帧动画
[UIView animateKeyframesWithDuration: delay: options: animations: completion:];
// 上面方法对应着CoreAniamation里面的CAKeyframeAnimation和CAAnimationGroup
CAKeyframeAnimation *transformAnima = [CAKeyframeAnimation animationWithKeyPath:@"transform.rotation.y"];
// ......具体动画属性设置
CAAnimationGroup *animaGroup = [CAAnimationGroup animation];
animaGroup.duration = 2.0f;
animaGroup.fillMode = kCAFillModeForwards;
animaGroup.removedOnCompletion = NO;
animaGroup.animations = @[transformAnima];
对应四:转场动画
[UIView transitionFromView: toView: duration: options: completion:];
[UIView transitionWithView: duration: options: animations: completion:];
// 上面方法对应着CoreAniamation里面的CATransition
CATransition *transition = [CATransition animation];
transition.duration = 0.25;
transition.type = kCATransitionMoveIn;
transition.subtype = kCATransitionFromRight;
[containerView.layer addAnimation:transition forKey:nil];
转场动画的类型
总结完毕!