前言
最近去面试,被面试官问到UIView与CALayer的关系是什么,想了一下支支吾吾地回答了:“UIView负责确定UI的位置,它包含CALAyer,CALayer负责视图内容的绘制位置大小确定等”,鉴于对两者之前的关系的理解的不够透彻,于是有了这篇文章。
首先我们要理解UIView以及它的一个继承关系等
UIView表示屏幕上的一块矩形区域,它是基本上iOS所有可视化控件的父类,UIView可以管理矩形区域里的内容,处理矩形区域的事件,包括对子视图的管理以及动画的实现。
UIKit的控件的继承关系(图片摘自网络):
上面的图是UIKit相关类的继承关系,从上面可以看出,UIView继承自UIResponder,所以UIView可以做事件响应,它也是iOS中所有视图(控件)直接或者间接的父类。
简单介绍一下UIResponder
在UIKit中UIResponder作为响应事件的对象,来响应系统传递过来的事件并进行处理。在UIResponder中定义了处理各种事件传递的接口。
UIApplication、UIViewController、UIView、和所有从UIView派生出来的UIKit类(包括UIWindow)都直接或间接地继承自UIResponder类。
而CALayer直接继承NSObject,并没有相应的处理事件的接口。
UIView和CALayer的关系
在每个UIView实例当中,都有一个默认的支持图层layer,UIView负责创建并且管理这个图层,实际上UIView之所以能够显示,就是因为它里面有这个一个层,才具有显示的功能,UView仅仅是对它的一层封装,实现了CALayer的delegate,提供了处理事件交互的具体功能,还有动画底层方法的高级API,可以说CALayer是UIView的内部实现细节。
如下图(图片来源于网络):
UIView与CALayer的区别
- UIView能够响应事件,CALayer不可以
- UIView是CALayer的delegate
- UIView只是处理事件,CALayer主要负责图层的绘制
- 每个UIView内部都有一个CALayer在背后提供内容绘制和显示,而且UIView的尺寸样式都由内部的Layer所提供。两者都有树状层级结构,layer内部有SubLayers,View内部有SubViews。但是Layer比View多了AnchorPoint
- 一个Layer的frame是由它anchorPoint,position,bounds,和 transform 共同决定的,而一个View的frame只是简单的返回Layer的frame
- 在iOS做动画的时候,修改非RootLayer的属性(譬如位置、背景色等)会默认产生隐式动画,而修改UIView则不会