Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 8 additions & 8 deletions 3-图层几何学/图层几何学.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

视图的`frame`,`bounds`和`center`属性仅仅是*存取方法*,当操纵视图的`frame`,实际上是在改变位于视图下方`CALayer`的`frame`,不能够独立于图层之外改变视图的`frame`。

对于视图或者图层来说,`frame`并不是一个非常清晰的属性,它其实是一个虚拟属性,是根据`bounds`,`position`和`transform`计算而来,所以当其中任何一个值发生改变,frame都会变化。相反,改变frame的值同样会影响到他们当中的值
`frame`并不是视图或图层的一个特有属性,它其实是一个虚拟属性,是根据`bounds`,`position`和`transform`计算而来的,所以当其中任何一个值发生改变时,frame都会变化。反过来也是一样,改变frame的值同样会影响到他们当中的一个或所有值。

记住当对图层做变换的时候,比如旋转或者缩放,`frame`实际上代表了覆盖在图层旋转之后的整个轴对齐的矩形区域,也就是说`frame`的宽高可能和`bounds`的宽高不再一致了(图3.2)

Expand All @@ -26,7 +26,7 @@
##锚点
之前提到过,视图的`center`属性和图层的`position`属性都指定了`anchorPoint`相对于父图层的位置。图层的`anchorPoint`通过`position`来控制它的`frame`的位置,你可以认为`anchorPoint`是用来移动图层的*把柄*。

默认来说,`anchorPoint`位于图层的中点,所以图层的将会以这个点为中心放置。`anchorPoint`属性并没有被`UIView`接口暴露出来,这也是视图的position属性被叫做“center”的原因。但是图层的`anchorPoint`可以被移动,比如你可以把它置于图层`frame`的左上角,于是图层的内容将会向右下角的`position`方向移动(图3.3),而不是居中了。
默认来说,`anchorPoint`位于图层的中点,所以图层将会以这个点为中心放置。`anchorPoint`属性并没有暴露在`UIView`的接口中,这也是视图的position属性被叫做“center”的原因。但是图层的`anchorPoint`可以被移动,比如你可以把它置于图层`frame`的左上角,于是图层的内容将会向右下角的`position`方向移动(图3.3),而不是居中了。

<img src="./3.3.jpeg" alt="图3.3" title="图3.3" width="700"/>

Expand Down Expand Up @@ -130,34 +130,34 @@
##坐标系
和视图一样,图层在图层树当中也是相对于父图层按层级关系放置,一个图层的`position`依赖于它父图层的`bounds`,如果父图层发生了移动,它的所有子图层也会跟着移动。

这样对于放置图层会更加方便,因为你可以通过移动根图层来将它的子图层作为一个整体来移动,但是有时候你需要知道一个图层的*绝对*位置,或者是相对于另一个图层的位置,而不是它当前父图层的位置
这样对于放置图层会更加方便,因为你可以通过移动根图层来将它的子图层作为一个整体来移动,但是有时候你需要知道一个图层的*绝对*位置,或者是相对于另一个图层的位置,而不是相对于它当前父图层的位置

`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;
- (CGRect)convertRect:(CGRect)rect toLayer:(CALayer *)layer;

这些方法可以把定义在一个图层坐标系下的点或者矩形转换成另一个图层坐标系下的点或者矩形

###翻转的几何结构

常规说来,在iOS上,一个图层的`position`位于父图层的左上角,但是在Mac OS上,通常是位于左下角。Core Animation可以通过`geometryFlipped`属性来适配这两种情况,它决定了一个图层的坐标是否相对于父图层垂直翻转,是一个`BOOL`类型。在iOS上通过设置它为`YES`意味着它的子图层将会被垂直翻转,也就是将会沿着底部排版而不是通常的顶部(它的所有子图层也同理,除非把它们的`geometryFlipped`属性也设为`YES`)。
常规说来,在iOS上,一个图层的`position`是相对于它父图层`bounds`的左上角来指定的,而在Mac OS上,则是左下角。Core Animation可以通过`geometryFlipped`属性来适配这两种情况,它决定了一个图层的坐标是否相对于父图层垂直翻转,是一个`BOOL`类型。在iOS上通过设置它为`YES`意味着它的子图层将会被垂直翻转,也就是将会沿着底部定位而不是通常的顶部(它的所有子图层也同理,除非把它们的`geometryFlipped`属性也设为`YES`)。

###Z坐标轴

和`UIView`严格的二维坐标系不同,`CALayer`存在于一个三维空间当中。除了我们已经讨论过的`position`和`anchorPoint`属性之外,`CALayer`还有另外两个属性,`zPosition`和`anchorPointZ`,二者都是在Z轴上描述图层位置的浮点类型。

注意这里并没有更*深*的属性来描述由宽和高做成的`bounds`了,图层是一个完全扁平的对象,你可以把它们想象成类似于一页二维的坚硬的纸片,用胶水粘成一个空洞,就像三维结构的折纸一样。

`zPosition`属性在大多数情况下其实并不常用。在第五章,我们将会涉及`CATransform3D`,你会知道如何在三维空间移动和旋转图层,除了做变换之外,`zPosition`最实用的功能就是改变图层的*显示顺序*了。
`zPosition`属性在大多数情况下其实并不常用。在第五章,我们将会涉及`CATransform3D`,你会知道如何在三维空间移动和旋转图层,但是除了做变换之外,`zPosition`唯一实用的功能可能就是改变图层的*显示顺序*了。

通常,图层是根据它们子图层的`sublayers`出现的顺序来类绘制的,这就是所谓的*画家的算法*--就像一个画家在墙上作画--后被绘制上的图层将会遮盖住之前的图层,但是通过增加图层的`zPosition`,就可以把图层向相机方向*前置*,于是它就在所有其他图层的*前面*了(或者至少是小于它的`zPosition`值的图层的前面)。
通常,图层是根据它们在父图层的`sublayers`数组中的顺序来被绘制的,这就是所谓的*画家的算法*--就像一个画家在墙上作画--后被绘制上的图层将会遮盖住之前的图层,但是通过增加图层的`zPosition`,就可以把图层向相机方向*前置*,于是它就在所有其他图层的*前面*了(或者至少是小于它的`zPosition`值的图层的前面)。

这里所谓的“相机”实际上是相对于用户是视角,这里和iPhone背后的内置相机没任何关系。

图3.8显示了在Interface Builder内的一对视图,正如你所见,首先出现在视图层级绿色的视图被绘制在红色视图的后面
图3.8显示了在Interface Builder内的一对视图,正如你所见,首先出现在视图层级的绿色视图被绘制在红色视图的后面

<img src="./3.8.jpeg" alt="图3.8" title="图3.8" width="700"/>

Expand Down