UIView和CALayer的关系

UIView是iOS系统中界面元素的基础,所有的界面元素都是继承自它。平时的开发中我们经常使用UIView,比如初始化一个UIView并设置它的frame、背景颜色等属性,但有时候UIView满足不了我们,比如:需要设置UIView的圆角和边框等操作,那么这个时候我们就会使用view.layer,即CALayer,那么两者之间到底有什么关系呢?

1、每个UIView都对应着一个CALayer,当我们创建了一个UIView之后也会创建对应的CALayer。UIView之所以能够显示内容,其实还是靠CALayer来绘制的。UIView本身就像是CALayer的管理者,访问UIView的坐标,例如:frame,center等,其实是访问内部layer的frame、position等相关属性。
2、UIView有一个layer属性,通过该属性我们可以获取它的主CALayer实例。该属性也告诉我们UIView是layer的代理UIView需要显示时,它内部的层会准备好一个CGContextRef(图形上下文),然后调用delegate(这里就是UIView)的drawLayer:inContext:方法,并且传入已经准备好的CGContextRef对象。而UIView在drawLayer:inContext:方法中又会调用自己的drawRect:方法。这样view就可以在drawRect:方法中实现绘图,所有的东西都被绘制到view.layer上,最终系统将view.layer的内容拷贝到屏幕上。
open var layer: CALayer { get } // returns view's layer. Will always return a non-nil value. view is layer's delegate
UIView还有一个UIView有一个layerClass属性,返回主layer所使用的类,对于UIView的子类,可以通过重载这个方法,来让UIView使用不同的CALayer来显示
open class var layerClass: Swift.AnyClass { get } // default is [CALayer class]. Used when creating the underlying layer for the view.
3、UIView继承自UIResponder, 所以它可以响应事件。而CALayer是直接继承自NSObject, 所以并不能响应事件。
4、在做 iOS 动画的时候, 修改非RootLayer(不是view的根layer)的属性(譬如位置, 背景色等)会默认产生隐式动画, 而修改UIView则不会。
5、UIView的layer树形在系统内部,被系统维护着三份copy。第一份,逻辑树,就是代码里可以操纵的,例如更改layer的属性等等就在这一份。第二份,动画树,这是一个中间层,系统正在这一层上更改属性,进行各种渲染操作。第三份,显示树,这棵树的内容是当前正被显示在屏幕上的内容。这三棵树的逻辑结构都是一样的,区别只有各自的属性。
6、坐标系系统是不一样的。CALayer的坐标系系统和UIView有点不一样,它多了一个叫anchorPoint的属性,它使用CGPoint结构,但是值域是0~1也就是按照比例来设置。这个点是各种图形变换的坐标原点,同时会更改layer的position的位置,它的默认值是{0.5, 0.5}也就是在layer的中心。
7、UIView的CALayer类似UIView的子View树形结构,竟然UIView可以添加子view,那么CALayer也可以向它的layer上添加子layer,来完成某些功能。
8、 layer可以设置圆角显示,例如UIButton的效果,也可以设置阴影显示,但是如果layer树中的某个layer设置了圆角,树中所有layer的阴影效果都将显示不了了。如果既想有圆角又想要阴影,好像只能做两个重叠的UIView,一个的layer显示圆角,一个的layer显示阴影.....

参考

详解CALayer和UIView的区别和联系

What are the differences between a UIView and a CALayer?




猜你喜欢

转载自blog.csdn.net/longshihua/article/details/79422371