图层与视图

一个视图就是在屏幕上显示的一个矩形块(比如图片,文字或者视频),它能够拦截类似于鼠标点击或者触摸手势等用户输入。视图在层级关系中可以互相嵌套,一个视图可以管理它的所有子视图的位置。如下图显示了一种典型的视图层级关系:

图层与视图_第1张图片

在iOS当中,所有的视图都从一个叫做 UIView的基类派生而来, UIView可以处理触摸事件,可以支持基于Core Graphics绘图,可以做仿射变换(例如旋转或者缩放),或者简单的类似于滑动或者渐变的动画。

CALayer

CALayer类在概念上和UIView类似,同样也是一些被层级关系树管理的矩形块,同样也可以包含一些内容(像图片,文字或者背景色),管理图层的位置。它们有一些方法和属性用来做动画和变换。和UIVIew最大的不同是CALayer不处理用户的交互。
CALayer并不清楚具体的响应链(iOS通过视图层级关系用来传送触摸事件的机制),于是它并不能够响应事件,即使它提供了一些方法来判断是否一个触点在图层的范围之内。

平行的层级关系

每一个UIView都有一个CALayer实例的图层属性,也就是所谓的backing layer,视图的职责就是创建并管理这个图层,以确保当子视图在层级关系中添加或者被移除的时候,他们关联的图层也同样在对应层级关系树当中有相同的操作,如下图:

图层与视图_第2张图片

实际上这些背后关联的图层才是真正用来在屏幕上显示和做动画,UIView仅仅是对它的一个封装,提供了一些iOS类似于处理触摸的具体功能,以及Core Animation 底层方法的高级接口。

但是为什么iOS要基于UIViewCALayer提供两个平行的层级关系呢?为什么不用一个简单的层级来处理所有的事情呢? 原因在于要做职责分离,这样也能避免很多重复代码。在iOS和Mac OS两个平台上,事件和用户交互有很多地方的不同,基于多点触控的用户界面和基于鼠标键盘有着本质的区别。

实际上这里并不是两个层级关系,而是四个,每一个都扮演不同的角色,除了视图层级和图层树之外,还有呈现树和渲染树。

图层的能力

图层既然不能像视图那样处理触摸事件,那么它能做哪些视图不能做的呢:

  • 阴影,圆角,带颜色的边框
  • 3D变换
  • 非矩形范围
  • 透明遮罩
  • 多级非线性动画

图层的使用

首先我们创建一个白色的视图,然后用CALayer给它添加一个蓝色的子图层:

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    self.view.backgroundColor = [UIColor grayColor];
    UIView *view = [[UIView alloc]init];
    view.frame = CGRectMake(80,200, 200, 200);
    view.backgroundColor = [UIColor whiteColor];
    [self.view addSubview:view];
    
    CALayer *blueLayer = [CALayer layer];
    blueLayer.frame = CGRectMake(50, 50, 100, 100);
    blueLayer.backgroundColor = [UIColor blueColor].CGColor;
    [view.layer addSublayer:blueLayer];
}

运行结果:

图层与视图_第3张图片

一个视图只有一个相关联的图层(自动创建),同时它也可以支持添加无数多个子图层,你可以显示创建一个单独的图层,并且把它直接添加到视图关联图层的子图层。尽管可以这样添加图层,但往往我们只是简单的处理视图,他们关联的图层并不需要额外地手动添加子图层。

你可能感兴趣的:(图层与视图)