总的来说: 每个UIView都封装了一个CALayer,UIView
负责处理用户交互,负责绘制内容的则是它持有的那个CALayer
,我们访问和设置UIView
的这些负责显示的属性实际上访问和设置的都是这个CALayer
对应的属性,UIView
只是将这些操作封装起来了而已。
形象理解就是UIView
就像电视机,CALayer
则是它的屏幕,对于观众来讲我们知道电视机能显示东西、能操作(开关机、换台等)、能设置和获取各种显示属性,比如亮度、对比度等。我们对电视机的各种命令都会改变它自身的显示,就像我们修改一个UIView
的背景色一样,电视机本身把如何显示的细节隐藏起来了,观众只需要简单的按个按钮(给UIView
设置一个属性)就能控制它的显示了。当我们获取和设置电视机当前的亮度时,电视机只是简单的去获取和设置它的显示屏的亮度而已。我们访问和设置UIView
的一些负责绘制规则的属性比如frame、center、backgroundColor等,在其持有的CALayer
中都存在对应的属性,UIView
只是简单的返回它自己CALayer
的属性以及对自己的CALayer
的这些对应的属性赋值而已。
具体的,CALayer是负责显示内容的、与图形显示有关的类,其属于QuartzCore
框架,这个框架是一个跨平台的绘制框架,而UIView类本身没有显示图形的功能,但它有一个CALayer类属性层,UIView实例通过管理自己的层来显示内容.
layer的delegate类就是创建layer的UIView实例,UIView类实现了CALayerDelegate
协议来为自己的layer提供图像内容。同时,UIView类继承自UIResponder类,所以可以交互交互事情做出反应。
这里的跨平台指的是在iOS和macOS系统上均能使用,也就是说CALayer
能在iOS和macOS上面绘制内容(这也说明了为什么CALayer
的很多属性都不是UIKit框架下面的东西,比如它的backgroundColor是CGColorRef
,因为macOS中没有UIKit)。但是这两个平台接收用户交互的方式完全不一样:iOS是通过触摸事件(touch event)而macOS则是监听鼠标和键盘事件。
苹果的工程师们考虑到:这两个平台的绘制规则(如何将一个像素显示到屏幕上)都是一样的,但是交互规则完全不一样。所以他们使用了同一种绘制方式和不同的交互方式,具体的,他们将CALayer
作为两个平台共同的用来绘制内容的类而针对交互方式,他们在iOS中使用了UIResponder
类来响应交互在macOS中则没有UIKit里面的类取而代之是叫做NSView
之类的东西。而通常情况下交互是发生在绘制内容之上的(有内容的地方才能点击),所以UIKit将CALayer
封装进了UIView
中,让开发者们感觉到UIView
既能绘制又能处理交互,而实际上负责绘制的是UIView
中的CALayer
。