飒飒东风细雨来,芙蓉塘外有轻雷。
金蟾啮锁烧香入,玉虎牵丝汲井回。
贾氏窥帘韩掾少,宓妃留枕魏王才。
春心莫共花争发,一寸相思一寸灰!
核心动画介绍
本质
- 核心动画都是假象,并不会改变layer的属性值
- 而UIView只有属性改变才会有动画
- 使用场景:- 如果在执行过程中不需要用户交互,就可以用核心动画
- 在转场动画中,核心动画用得比较多
 
CAAnimation的继承结构:
- 要想执行动画,就必须初始化一个CAAnimation对象。
- 其实,一般情况下,我们使用的比较多的是CAAnimation的子类,因此,先大致看看CAAnimation的继承结构:

CAAnimation
- 所有动画对象的父类,负责控制动画的持续时间和速度,是个抽象类,不能直接使用,应该使用它具体的子类。
- 属性解析: - duration:动画的持续时间
- repeatCount:动画的重复次数
- repeatDuration:动画的重复时间
- removedOnCompletion:默认为YES,代表动画执行完毕后就从图层上移除,图形会恢复到动画执行前的状态。如果想让图层保持显示动画执行后的状态,那就设置为NO,不过还要设置fillMode为- kCAFillModeForwards
- fillMode:决定当前对象在非active时间段的行为.比如动画开始之前,动画结束之后
- beginTime:可以用来设置动画延迟执行时间,若想延迟2s,就设置为CACurrentMediaTime()+2,- CACurrentMediaTime()为图层的当前时间
- timingFunction:速度控制函数,控制动画运行的节奏
- delegate:动画代理
 
- timingFunction可选的值有:
| 1 | // (线性):匀速,给你一个相对静态的感觉 | 
CAAnimation——动画代理方法
| 1 | // CAAnimation在分类中定义了代理方法 | 
CAPropertyAnimation
- 是CAAnimation的子类,也是个抽象类,要想创建动画对象,应该使用它的两个子类:CABasicAnimation和CAKeyframeAnimation
- 属性说明:- keyPath:通过指定CALayer的一个属性名称为- keyPath(NSString类型),并且对CALayer的这个属性的值进行修改,达到相应的动画效果。
- 比如,指定@”position”为keyPath,就修改CALayer的position属性的值,以达到平移的动画效果。
 
CALayer
- 在iOS中,你能看得见摸得着的东西基本上都是UIView,比如一个按钮、一个文本标签、一个文本输入框、一个图标等等,这些都是UIView。
- 其实UIView之所以能显示在屏幕上,完全是因为它内部的一个图层。
- 在创建UIView对象时,UIView内部会自动创建一个图层(即CALayer对象),通过UIView的layer属性可以访问这个层。
| 1 | @property(nonatomic,readonly,retain) CALayer *layer; | 
- 当UIView需要显示到屏幕上时,会调用drawRect:方法进行绘图,并且会将所有内容绘制在自己的图层上,绘图完毕后,系统会将图层拷贝到屏幕上,于是就完成了UIView的显示。
- 换句话说,UIView本身不具备显示的功能,是它内部的层才有显示功能。
图层的常见属性应用
| 1 | /** 图像图层的属性 | 
图层的形变属性
| 1 | /** transfor属性 | 
自定义图层
- UIView *view;
- view.layer.delegate == view;
- view的完整显示过程 - view.layer会准备一个Layer Graphics Contex(图层类型的上下文)
- 调用view.layer.delegate(view)的drawLayer:inContext:,并传入刚才准备好的上下文
- view的drawLayer:inContext:方法内部又会调用view的drawRect:方法
- view就可以在drawRect:方法中实现绘图代码, 所有东西最终都绘制到view.layer上面
- 系统再将view.layer的内容拷贝到屏幕,于是完成了view的显示
 
- view.layer会准备一个
- 自定义层,其实就是在层上绘图,一共有2种方法,下面详细介绍一下。 
自定义图层方法1
- 方法描述:创建一个CALayer的子类,然后覆盖drawInContext:方法,使用Quartz2D API进行绘图
| 1 | - (void)diyLayer | 
自定义的图层方法2
- 方法描述:创建一个CALayer的子类,然后覆盖drawInContext:方法,使用uartz2D API进进行绘图
| 1 | 
 | 
CALayer上动画的暂停和恢复
| 1 | 
 | 
隐式动画
- 每一个UIView内部都默认关联着一个CALayer,我们可用称这个Layer为Root Layer(根层)
- 所有的非Root Layer,也就是手动创建的CALayer对象,都存在着隐式动画
- 什么是隐式动画? - 当对非RootLayer的部分属性进行修改时,默认会自动产生一些动画效果,而这些属性称为AnimatableProperties(可动画属性)
 
- 当对
- 列举几个常见的Animatable Properties: - bounds:用于设置CALayer的宽度和高度。修改这个属性会产生缩放动画
- backgroundColor:用于设置CALayer的背景色。修改这个属性会产生背景色的渐变动画
- position:用于设置CALayer的位置。修改这个属性会产生平移动画
 
事务
- 可以通过动画事务(CATransaction)关闭默认的隐式动画效果
| 1 | [CATransaction begin]; | 
CALayer注意点
关于CALayer的疑惑
- 为什么CALayer中使用CGColorRef和CGImageRef这2种数据类型,而不用UIColor和UIImage?
- 首先- CALayer是定义在QuartzCore框架中的,CGImageRef、CGColorRef两种数据类型是定义在CoreGraphics框架中的。
- UIColor、UIImage是定义在UIKit框架中的。
 
- CALayer是定义在
- 其次- QuartzCore框架和CoreGraphics框架是可以跨平台使用的,在iOS和Mac OS X上都能使用。
- 但是UIKit只能在iOS中使用。
 
- QuartzCore框架和CoreGraphics框架是可以
- 为了保证可移植性,QuartzCore不能使用UIImage、UIColor,只能使用CGImageRef、CGColorRef。
UIView和CALayer的选择
- 通过CALayer,就能做出跟UIImageView一样的界面效果,既然CALayer和UIView都能实现相同的显示效果,那究竟该选择谁好呢?- 其实,对比CALayer,UIView多了一个事件处理的功能。也就是说,CALayer不能处理用户的触摸事件,而UIView可以。
- 所以,如果显示出来的东西需要跟用户进行交互的话,用UIView;如果不需要跟用户进行交互,用UIView或者CALayer都可以。
- 当然,CALayer的性能会高一些,因为它少了事件处理的功能,更加轻量级。
 
position和anchorPoint
- CALayer有2个非常重要的属性:position和anchorPoint
| 1 | // 用来设置CALayer在父层中的位置 | 
UIView和CALayer的其他关系
- UIView可以通过subviews属性访问所有的子视图,类似地,CALayer也可以通过sublayers属性访问所有的子层
- UIView可以通过superview属性访问父视图,类似地,CALayer也可以通过superlayer属性访问父层
- 下面再看一张UIView和CALayer的关系图: 
- 如果两个UIView是父子关系,那么它们内部的CALayer也是父子关系。
常用的CALayer子类
CAReplicatorLayer(复制层)
- 结合音量振动条的简单使用
| 1 | - (void)viewDidLoad | 
CAGradientLayer(渐变层)
| 1 | 
 | 
CAShapeLayer(形状图层)
- 结合QQ bage消息的粘性计算实例
| 1 | - (CAShapeLayer *)shapeLayer | 
- QQ bage消息的粘性计算图  
- 计算方法 
| 1 | // 计算不规则的矩形路径 |