图层几何学
1. 布局
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宽高不再保持一致.
2. 锚点
anchorPoint默认位于图层的中点, 所以图层将会以这个点为中心放置. 图层的anchorPoint是可以被移动的, 比如当把它置于图层frame的左上角, 于是图层内容将会向右下角的Position方向移动.
anchorPoint也使用单位坐标来描述. 当改变anchorPoint时候, Position属性保持固定, 但是frame却会发生变化.
一个移动anchorPoint而不该表frame的方法:
简单地说, 就是改变Position, 测试发现, 例如, 将anchorPoint移动到左上角, 正常情况下, frame会向右下角移动0.5的单位, 如果改变anchorPoint的同时, 更改Position, Position的向左上角移动0.5*frame.size.width, 这时候, frame看起来就是不动的.
不过这点关系, 还是有点迷糊.....
3. 坐标系
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;
4. z坐标轴
UIView位于严格的二维坐标系中, CALayer存在于三维空间中, 它的aPosition和anchorPointZ都是在z轴上面描述图层位置的浮点类型. zPosition在大多数情况下不常用, 它的主要功能就是改变图层的显示顺序.
最好使用图层相关的视图, 而不直接使用图层, 主要原因是因为要处理额外的复杂的触摸事件. 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");
}
}
来源:oschina
链接:https://my.oschina.net/u/2501614/blog/725886