UIView有三个比较重要的属性: frame, bounds, center. CALayer对应的叫作: frame,bounds,position. frame表明图层外部坐标, bounds是内部坐标.工具
视图的frame, bounds, center属性仅仅是存取方法, 当操做视图的frame时候,其实是改变位于视图下方CALayer的frame, 不能独立于图层以外改变视图的frame. 对于视图和图层来讲, frame并非一个很是清晰的属性,他实际上是一个虚拟的属性, 是根据bounds, position和transform计算而来的, 当其中任意一值发生变化, frame都会变化, 一样的, frame也会影响到他们当中的值.布局
当图层作变换时候, 好比旋转或者缩放, frame实际上表明的是覆盖在图层旋转以后的整个轴对称对齐的矩形区域, 就是说, frame和bounds宽高再也不保持一致.测试
anchorPoint默认位于图层的中点, 因此图层将会以这个点为中心放置. 图层的anchorPoint是能够被移动的, 好比当把它置于图层frame的左上角, 因而图层内容将会向右下角的Position方向移动.3d
anchorPoint也使用单位坐标来描述. 当改变anchorPoint时候, Position属性保持固定, 可是frame却会发生变化.code
一个移动anchorPoint而不应表frame的方法:orm
简单地说, 就是改变Position, 测试发现, 例如, 将anchorPoint移动到左上角, 正常状况下, frame会向右下角移动0.5的单位, 若是改变anchorPoint的同时, 更改Position, Position的向左上角移动0.5*frame.size.width, 这时候, frame看起来就是不动的.对象
不过这点关系, 仍是有点迷糊.....blog
CALayer给不一样坐标系之间的图层转换提供了一些工具类方法, 相似于视图之间坐标系的转换方法:事件
- (CGPoint)convertPoint:(CGPoint)point fromLayer:(CALayer *)layer; - (CGPoint)convertPoint:(CGPoint)point toLayer:(CALayer *)layer; - (CGRect)convertRect:(CGRect)rect fromLayer:(CALayer *)layer; - (CGRect)convertRect:(CGRect)rect toLayer:(CALayer *)layer;
UIView位于严格的二维坐标系中, CALayer存在于三维空间中, 它的aPosition和anchorPointZ都是在z轴上面描述图层位置的浮点类型. zPosition在大多数状况下不经常使用, 它的主要功能就是改变图层的显示顺序.get
最好使用图层相关的视图, 而不直接使用图层, 主要缘由是由于要处理额外的复杂的触摸事件. CALayer并不关心任何响应链事件, 因此不能直接处理触摸事件或者手势. 可是它也有几个方法能够帮你处理事件: -containsPoint:和-hitTest:
。
-containsPoint: 接受一个在本图层坐标系下的CGPoint, 若是点在bounds内, 返回YES. 缺点是, 若是使用这种方法, 须要将发生事件的位置, 转换到每个layer坐标系当中去, 不方便.
-hitTest: 一样接受一个CGPoint类型参数, 返回值是图层自己, 既发生点击事件的图层. 若是点不在此图层树范围内, 则返回nil.
code:
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event { //获取发生在view上的一个点 CGPoint point = [[touches anyObject] locationInView:self.view]; //经过hitTest方法找到点在哪一个layer上面. 返回值是CALayer对象, UIView也有相关的方法 CALayer *targetLayer = [self.view.layer hitTest:point]; if (targetLayer == self.greenLayer) { NSLog(@"绿色 layer"); } if (targetLayer == self.redLayer) { NSLog(@"红色 layer"); } }