图层树
- 图层与视图
- 图层的能力
- 使用图层
- 总结
Core Animation
是一个复合引擎, 他的职责是尽可能的组合屏幕的不同的可视内容, 这个内容是被分解为独立的图层, 存储在一个叫做图层树的体系之中, 于是这个树形成了UIKit以及iOS应用程序当中你能在屏幕上看到的一切的基础
在讨论动画之前, 我们将从图层树开始, 涉及一下core Animation
的静态组合以及布局特性
一: 图层与视图
一个视图就是在屏幕上显示的一个矩形块, 他能够拦截类似鼠标点击或者触摸手势等输入行为, 视图在层级关系中可以互相嵌套, 一个视图可以管理他的所有子视图的位置
一种典型的iOS屏幕和形成视图的层级关系
在iOS中, 所有的视图都是从一个叫做UIView的基类派生出来的, UIView可以处理触摸事件, 可以支持基于core Graphics
绘图, 可以做仿射变换(旋转或者缩放). 或者简单的类似滑动或者渐变的动画
1.1: CALayer
CALayer
类在概念上和UIView
相似, 同样也是一些被层级关系树管理的矩形块, 同样也可以包含一些内容(图片、文本、背景色)管理子图层的位置, 它们有有些方法和属性用来做动画和变换, 和UIView最大的不同是CALayer不处理用户的交互.
CALayer
并不清楚具体的响应链(iOS通过视图层级关系来传送触摸事件的机制), 于是他不能够响应事件, 即使她提供了一些方法来判断是否一个触电是否在图层范围内
1.2: 平行的层级关系
每个UIView都有一个CALayer实例的图层属性, 也就是所谓的backing layer
, 视图的职责是创建并管理这个图层, 以确保子视图在层级关系中添加和移除的时候, 他们关联页同样对应层级关系书当中的相同操作
[图片上传失败...(image-e7891f-1512703987307)]
实际上这些背后关联的图层碍事真正用来在屏幕上下显示和做动画的, UIView仅仅是对他的封装, 提供了一些iOS相关处理触摸的具体功能, 以及Core Animation
底层方法的高级接口
但是为什么iOS要基于UIView
和CALayer
提供两个平行的层级关系那? 为什么不用一个简单的层级来处理所有的事情那? 原因在于职责分离
, 这样能避免很多重复代码
, 在iOS和MacOS两个平台下, 事情和用户交互很多地方的不同, 基于多点触控的用户界面和基于鼠标键盘有着本质的区别, 这就是iOS有UIKit和UIView, 但是Mac OS有AppKit和NSView的原因, 他们功能很相似, 但是在实现上有着显著的区别
绘图、布局和动画, 相比之下就是类似Mac比较本和桌面系列一样应用于iPhone和Ipad触屏的概念, 吧这种功能的逻辑分开并应用到独立的Core Animation
框架中, 苹果就能够在iOS和Mac OS之间共享代码, 使得对苹果自己的OS开发团队和第三方开发者去方法两个平台更加便捷
实际上, 这里并不是两个层级关系, 而是四个,每一个都扮演不同的角色, 除了视图层级和图层树之外, 还存在呈现树和渲染树.
1.3: 图层的能力
如果说CALayer是UIView的内部实现细节, 那我们为什么要全面的了解他吶? 苹果当然为我们提供了优美简洁的UIView接口, 那么我们是否就没有必要直接处理Core Animation
某种意义上说的的确实这样的, 对一些简单的需求来说, 我们没有必要处理CALayer, 因为苹果已经通过UIView
的高级API间接的使得动画变得很简单
我们已经证实图层不能像视图那样带来一些灵活上的缺陷, UIView缺少CALayer的功能
- 阴影 圆角 带颜色的边框
- 3D变换
- 非矩形范围
- 透明遮罩
- 多级非线性动画
1.4:使用图层
首先我们来创建一个简单的图层, 从屏幕中央创建一个小视图(200*200),
灰色的视图有一个白色的小视图
我们来创建一个CALayer
, 并且把它作为我们视图相关图层的子图层, 我们创建一个CALayer
, 设置他的backgroundColor
属性, 然后添加到相应的Layer上。
[图片上传失败...(image-60588-1512703987307)]
#import "ViewController.h"
@interface ViewController ()
@property (nonatomic, strong)UIView *whiteView;
@property (nonatomic, strong)CALayer *blueLayer;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor grayColor];
[self.view addSubview:self.whiteView];
[self.whiteView.layer addSublayer:self.blueLayer];
}
- (UIView *)whiteView{
if (_whiteView == nil) {
_whiteView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 200, 200)];
_whiteView.backgroundColor = [UIColor whiteColor];
_whiteView.center = self.view.center;
}
return _whiteView;
}
- (CALayer *)blueLayer{
if (_blueLayer == nil) {
_blueLayer = [CALayer layer];
_blueLayer.frame = CGRectMake(50, 50, 100, 100);
_blueLayer.backgroundColor = [UIColor blueColor].CGColor;
}
return _blueLayer;
}
@end
使用图层关联的视图而不是CALayer
的好处在于, 你可以使用CALayer
底层的特性的同时, 也可以使用UIView
的高级API(自动排版、布局和事件处理)
如果满足一下的条件, 你可能需要使用CALayer
而不是UIView
- 开发同时可以在
Mac OS
上允许的跨平台应用 - 使用多种
CALayer
的子类, 并且不想创建额外的UIView
去包装他们所有 - 做一些对性能特别挑剔的工作, 比如对
UIView
一些可以忽略不计的操作都会引起显著的不同
处理视图比处理Layer要方便一些
网友评论