不管是面试还是日常开发涉及到动画方面的时候,我们总能用到 CALayer,那么 CALayer 和 UIView 到底有什么联系和区别呢?
一,CALayer 和 UIView 的关系
1, 我们知道 UIView 可以响应用户的事件, 而 CALayer 不可以
这是因为 UIView 继承于 UIResponder,所以可以响应用户事件,而 CALayer 继承于 NSObject,无法响应事件,
2, UIView 之所以能显示出来是因为它内部的一个 '层'(即 CALayer 对象), 通过 UIView 的 layer 属性可以访问到这个层,当 UIView 需要显示到屏幕上时,会调用 drawrect: 方法进行绘图,并且会将所有内容绘制到自己的层上, 绘图完毕后,系统会将层拷贝到屏幕上,这样就完成了 UIView 的显示.
3,坐标位置的关系对比
UIView中有 frame,bounds,center
CALayer 中有 frame,bounds,position,anchorPoint
在这些属性中frame 和 bounds 都相同
但是 CALayer 中多了特有的position 和anchorPoint(锚点)
先来了解一下 position 和 anchorPoint 的概念
比如说在一个桌子上有一张白纸,在白纸上有一个图钉(📌),
position是相对于桌面来说的,锚点是相对于白纸来说的,转化到 iOS 中来就是,有一个 layer 和 superLayer , position是相对于 superLayer来说的, 锚点是相对于layer来说的,
总结一下就是:
1, frame.origin 原点是指子视图的左上角相对于父视图的左上角的坐标
2, anchorPoint 是一个点,指的是锚点相对于它本身的 layer 所在的位置,范围是 (01,01),比如说锚点是(0,0)指左上角,(1,1)指右下角, 默认是 (0.5,0.5),锚点其实指的是一个比例
3, position,指的是锚点相对于 superlayer 的位置,
接下来说一下anchorPoint、position、frame之间的关系
如果知道 layer 的 frame 和 锚点,那么 layer 的 position 可以有以下公式计算得到:
position.x = frame.origin.x + anchorPoint.x * bounds.size.width;
position.y = frame.origin.y + anchorPoint.y * bounds.size.height;
下面再来看另外一个问题,如果单方面修改layer的position位置,会对anchorPoint有什么影响呢?修改anchorPoint又如何影响position呢?
根据代码测试,两者互不影响,受影响的只会是frame.origin,也就是layer坐标原点相对superLayer会有所改变。换句话说,frame.origin由position和anchorPoint共同决定,上面的公式可以变换成下面这样的:
frame.origin.x = position.x - anchorPoint.x * bounds.size.width;
frame.origin.y = position.y - anchorPoint.y * bounds.size.height;
这就解释了为什么修改anchorPoint会移动layer,因为position不受影响,只能是frame.origin做相应的改变,因而会移动layer。
二,CALayer 和 UIView 的选择
如果需要响应用户的交互,那么就选择 UIView,
如果不需要交互,使用 CALayer 会性能更好一些,
总结
一,anchorPoint是图层在旋转时的固定点(就好比图钉例子)
二,单方面修改anchorPoint或者position并不会对彼此产生影响,修改其中一个值,受影响的只会是frame.origin.
三,anchorPoint和position共同决定了frame
frame.origin.x = position.x - anchorPoint.x bounds.size.width;
frame.origin.y = position.y - anchorPoint.y bounds.size.height