CoreAnimation是一个复合引擎,它的职责就是尽可能快地组合屏幕上不同的可视内容,这个内容是被分解成独立的图层,存储在一个叫做图层树的体系之中。于是这个树就形成了UIKit以及在iOS应用程序当中你所能在屏幕上看到的一起的基础。
一、图层与视图
一个视图就是在屏幕上显示的一个矩形块,它能够拦截类似于鼠标点击或者触摸手势等用户输入。视图可以相互嵌套。
在iOS中,所有的视图都从一个叫做UIView的基类派生而来,UIView可以处理触摸事件,可以支持基于Core Graphics绘图,可以做放射变换,或者简单的类似于滑动或者渐变的动画。
1、CALayer
CALayer在概念上和UIView类似,同样也是一些被层级关系树管理的矩形块,同样也可以包含一些内容,管理子图层的位置。和UIView不同的是CALayer不处理用户的交互,CALayer并不清楚具体的响应链。
2、平行的层级关系
每一个UIView都有一个CALayer实例的图层属性,也就是所谓的backing layer,视图的职责就是创建并管理这个图层,以确保当子视图在层级关系中添加或者被移除的时候,他们关联的图层也同样对应在层级关系树中相同的操作。
UIView仅仅是对它的一个封装,提供了一些iOS类似于处理触摸的具体功能,以及Core Animation底层方法的高级接口。
为什么提供提供基于UIView和CALayer两个平行的层级关系呢?
答:原因在于要做职责分离,避免重复代码,在iOS和Mac OS两个平台上,事件和用户交互有很多地方的不同,基于多点触摸的用户界面和基于鼠标键盘有着本质的区别,这就是为什么iOS有UIKit的UIView,但是Mac OS有AppKit和NSView的原因。
二、图层的能力
某种意义上说的确这样,对一些简单的需求来说,我们确实没必要处理CALayer,因为苹果已经通过UIView的高级API间接地使得动画变得很简单。一些UIView没有暴露出来的CALayer的功能:
- 阴影,圆角,带颜色的边框
- 3D变换
- 非矩形范围
- 透明遮照
- 多级非线性动画
三、使用图层
CoreAnimation需要添加QuartzCore库。
@interface ViewController ()
@property (nonatomic, strong) UIView *layerView;
@end
@implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
//create sublayer
CALayer *blueLayer = [CALayer layer];
blueLayer.frame = CGRectMake(50.0f, 50.0f, 100.0f, 100.0f);
blueLayer.backgroundColor = [UIColor blueColor].CGColor;
//add it to our view
[self.layerView.layer addSublayer:blueLayer];
}
@end
一个视图只有一个相关联的图层(自动创建),同时它也可以支持添加无数多个子图层。
使用图层关联的视图而不是CALayer的好处在于,你能在使用所有CALayer底层特性的同时,也可以使用UIView的高级API。
当满足一下条件的时候,可能需要使用CALayer而不是UIView:
- 开始同时可以在Mac OS上运行的跨平台应用
- 使用多种CALayer的子类,并不想创建额外的UIView去封装他们所有
总的来说,处理视图会比单独处理图层更加方便。