飒飒东风细雨来,芙蓉塘外有轻雷。
金蟾啮锁烧香入,玉虎牵丝汲井回。
贾氏窥帘韩掾少,宓妃留枕魏王才。
春心莫共花争发,一寸相思一寸灰!
核心动画介绍
本质
- 核心动画都是假象,并不会改变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 | // 计算不规则的矩形路径 |