iOS CALayer中position和anchorPoint关系正确解读

前言

第一:本文揭示了决定CALayer 大小和位置的其实是它的属性bounds和position;CALayer的frame属性,实际上是从bounds和position属性中的值派生的,并且使用频率较低。也即frame的origin是通过position得到的,frame的size是通过bounds的size得到的。
第二:anchorPoint和position根本不是一个点。并不是网上说的那样position是layer中的anchorPoint点在superLayer中的位置坐标。

CALayer的坐标系类型

CALayer有两种坐标系类型:"基于点的坐标系""基于单位的坐标系";使用哪种坐标系取决于所传达的信息类型。
ⅰ、指定直接映射到屏幕坐标的值或必须相对于另一个图层指定的值时使用基于点的坐标,例如图层的position属性。基于点的坐标系相关的属性:bounds、position、frame
ⅱ、当值不应与屏幕坐标相关联时使用单位坐标,因为它与某个其他值相关。例如,图层的anchorPoint属性指定相对于图层本身边界的点,该点可以更改。基于单位的坐标系相关的属性:anchorPoint.

先介绍下这四个属性:

@property  frame  当前layer相当于 superLayer的坐标系,frame.origin是相对于superLayer左上角的位置,frame.size就是当前layer的大小。这个和UIView的frame是类似的。

@property  bounds  当前layer相对于自身的坐标系,bounds.size 和 frame.size是一样的。bounds.origin是相对于自身的左上角的位置。因此bounds.origin = (0,0);

@property  position  是当前layer上的一个点,相对于superLayer左上角的位置。这个position和frame.origin有何区别呢?下面会讲到。

@property  anchorPoint  该值是相对bounds.size的比例值来确定的. 例如(0,0), (1,1)分别表示左上角、右下角,依此类推.锚点都是对于自身来讲的. 确定自身的锚点,通常用于做相对的tranform变换.当然也可以用来确定位置.

四者之间的关系:

frame 和 bounds 之间的关系很简单, frame.origin = CGMakePoint(0,0)就是bounds。

CALayer中决定Layer大小和在superLayer中位置的是bounds 和 position尽管Layer具有frame属性,但该属性实际上是从bounds和position属性中的值派生的,并且使用频率较低。

anchorPoint、position、frame之间的相对关系.

Ⅰ、当确定锚点时,改变frame时, position的值为:
position.x= frame.origin.x+ anchorPoint.x* bounds.size.width;
position.y= frame.origin.y+ anchorPoint.y* bounds.size.height;

Ⅱ、当确定锚点时,改变position时, frame的值为:
frame.origin.x= position.x- anchorPoint.x* bounds.size.width; 
frame.origin.y= position.y- anchorPoint.y* bounds.size.height;

Ⅲ、改变锚点, frame的值变化为:
frame.origin.x= - anchorPoint.x* bounds.size.width+ position.x; 
frame.origin.y= - anchorPoint.y* bounds.size.height+ position.y;

影响关系

第一条关系说明:锚点不变时,frame改变,position会随着变化
第二条关系说明:锚点不变时,position变化,frame会随着变化
第三条关系说明:锚点改变, position不影响,frame会随着变化

为什么第三条关系中的锚点改变了,变化的是frame,而不是 position呢?因为position是真正相对于superLayer的位置。而frame.origin只是通过anchorPoint关系被动推到出来的,当改变anchorPoint的值时,改变的是frame的origin就可以看出position是实际位置的控制点,当锚点变化时,position的值是固定不变的。动态变化的是frame的origin。

网上一大堆说position是layer中的anchorPoint点在superLayer中的位置坐标(即同一个点,在不同坐标系的表现), 那为什么anchorPoint改变了,变得不是position的值,而是frame的,是不是很疑惑。真相只有一个position和anchorPoint根本就不是一个点, 因为它俩改变哪一个值,另一个值都不会改变的。Ⅱ和Ⅲ的关系中分别改变position的值和anchorPoint的值,被动改变者都是frame。position没有因为anchorPoint的改变而改变。anchorPoint也没有因为position的改变而改变。

代码验证:

anchorPoint不变,改变frame 时,position的值改变了

关系变化图一

anchorPoint不变,改变position 时,frame的值改变了

关系变化图二

anchorPoint变化时,position不变,frame改变了。

关系变化图三

总结:

当你在做Core Animation时,牵涉到rotation、scale、translation、position、frame改变时,就会用到anchorPoint或者position。正确的理解anchorPoint、position、frame的关系,你才能制作出炫酷美妙的动画。

推荐阅读更多精彩内容