图层几何学
UIView 有三个比较重要的布局属性: frame、bounds、center。CALayer 对应的分别叫做: frame、bounds、position
center/position 都代表了图层相对于父图层 anchorPoint 所在的位置
锚点
默认 anchorPoint 位于图层的中点,所以图层的将会以这个点为中点放置
anchorPonit 用单位坐标来描述。 左上角 {0, 0}, 右下角 {1, 1}, 默认 {0.5, 0.5}.也可以设置x、y 坐标小与0 或者 大于 1,将它设置在图层之外
备注: 当改变了 anchorPoint, position 属性是保持固定的。但是 frame 改变了
view.layer.anchorPoint = CGPointMake(0.5f, 0.9f)
坐标系
常规来说,在ios上,一个图层的position 位于父图层的左上角,但是在Mac OS上,通常是位于左下角。Core Animation 可以通过 geometryFlipped 属性来适配这2种情况。它决定了一个图层的坐标是否相对于父图层垂直翻转,是一个Bool 类型。
在ios上,通过设置它为yes,意味着它的子图层将会被垂直翻转,也就是将会沿着底部排版而不是通常的顶部
Z坐标轴
和UIView严格的二维坐标系不同,CALayer存在于一个三维空间当中。除了 position 和 anchorPoint 之外,还有 zPosition 和 anchorPointZ 两个属性。二者都是在 Z 轴上描述图层位置的浮点类型
a.layer.zPosition = 1.0f (先add a,再 add b。按理是 b覆盖 a。设置 zPosition后,a 被提到上面,覆盖 b)
Hit Testing
CALayer 并不关心任何响应链事件,所以不能直接处理触摸事件或手势。但是它有一系列的方法帮你处理事件: -containsPoint: 和 -hitTest
-containsPoint: 接受一个在本图层坐标系下的 CGPoint,如果这个点在图层 frame 范围内就返回 YES
-hitTest:方法统一接受一个 CGPoint 类型参数,它返回图层本身,或者包含这个坐标点的叶子节点图层
注意:当调用图层的 -hitTest: 方法时,测算的顺序严格依赖于图层树中的图层顺序(和UIView处理事件类似)。之前提到的 zPosition 属性可以明显改变屏幕上的图层的顺序,但是不能改变事件的传递顺序。
当使用视图的时候,可以充分的利用 UIView 类接口暴露出来的 UIViewAutoresizingMask 和 NSLayoutConstraint API, 但如果想随意控制CALayer 的布局,就要手工操作。最简单的方法就是使用 CALayerDelegate 如下函数
- (void)layoutSublayersOfLayer:(CALayer *)layer;
当图层的 bounds 发生改变,或图层的 -setNeedsLayout 方法被调用的时候,这个函数将会被执行。这使得你可以手动的重新摆放或重新调整子图层的大小。但是不能像 UIView 的 autoresizingMask 和 constraints 属性做到自适应屏幕旋转。