ios开发讲解之anchorPoint和position详解

来源:互联网 发布:keras中三维数据shape 编辑:程序博客网 时间:2024/05/17 05:11

引言

        相信初接触到CALayer的人都会遇到以下几个问题:  为什么修改anchorPoint会移动layer的位置?CALayerposition点是哪一点呢? anchorPointposition有什么关系?

         每一个UIView都默认关联着一个CALayer, UIViewframeboundscenter三个属性,CALayer也有类似的属性,分别为frameboundspositionanchorPoint。那positionanchorPoint是什么呢?先看看两者的原型,可知都是CGPoint点。

      @property CGPoint position ;

      @property CGPoint anchorPoint ;



anchorPoint

      一般都是先介绍position,再介绍anchorPoint。这里反过来,先来说说anchorPoint

       从一个例子开始入手吧,想象一下,把一张A4白纸用图钉订在书桌上,如果订得不是很紧的话,白纸就可以沿顺时针或逆时针方向围绕图钉旋转,这时候图钉就起着支点的作用。我们要解释的anchorPoint就相当于白纸上的图钉,它主要的作用就是用来作为变换的支点,旋转就是一种变换,类似的还有平移、缩放。

       继续扩展,很明显,白纸的旋转形态随图钉的位置不同而不同,图钉订在白纸的正中间与左上角时分别造就了两种旋转形态,这是由图钉(anchorPoint)的位置决定的。如何衡量图钉(anchorPoint)在白纸中的位置呢?在iOS中,anchorPoint点的值是用一种相对bounds的比例值来确定的,在白纸的左上角、右下角,anchorPoint分为为(0,0), (1, 1),也就是说anchorPoint是在单元坐标空间(同时也是左手坐标系)中定义的。类似地,可以得出在白纸的中心点、左下角和右上角的anchorPoint(0.5,0.5), (0,1), (1,0)


然后再来看下面两张图:

ios开发讲解之anchorPoint和position详解

                                          1.  anchorPoint = CGPointMake(0.5, 0.5)


ios开发讲解之anchorPoint和position详解                                                                              2.  anchorPoint = CGPointMake(0.0, 0.0);


然后执行旋转同样角度后的结果:

    ios开发讲解之anchorPoint和position详解


ios开发讲解之anchorPoint和position详解



position

       确切地说,positionlayer中的anchorPoint点在superLayer中的位置坐标。因此可以说, position点是相对suerLayer的,anchorPoint点是相对layer的,两者是相对不同的坐标空间的一个重合点。

      再来看看position的原始定义: The layer’s position in its superlayer’s coordinate space 中文可以理解成为positionlayer相对superLayer坐标空间的位置,很显然,这里的位置是根据anchorPoint来确定的.



anchorPointpositionframe

      anchorPoint的默认值为(0.5,0.5),也就是anchorPoint默认在layer的中心点。默认情况下,使用addSublayer函数添加layer时,如果已知layerframe值,根据上面的结论,那么position的值便可以用下面的公式计算:

position.x = frame.origin.x + 0.5 * bounds.size.width; position.y = frame.origin.y + 0.5 * bounds.size.height;

里面的0.5是因为anchorPoint取默认值,更通用的公式应该是下面的:

position.x = frame.origin.x + anchorPoint.x *bounds.size.width; position.y = frame.origin.y + anchorPoint.y *bounds.size.height;


特别注意

下面再来看另外两个问题,如果单方面修改layerposition位置,会对anchorPoint有什么影响呢?修改anchorPoint又如何影响position呢?  

根据代码测试,两者互不影响,受影响的只会是frame.origin,也就是layer坐标原点相对superLayer会有所改变。换句话说,frame.originpositionanchorPoint共同决定,上面的公式可以变换成下面这样的:

frame.origin.x = position.x - anchorPoint.x *bounds.size.width; frame.origin.y = position.y - anchorPoint.y *bounds.size.height;

这就解释了为什么修改anchorPoint会移动layer,因为position不受影响,只能是frame.origin做相应的改变,因而会移动layer


理解与运用

        因为 position点和anchorPoint点是独立的,自己不会因为另外一个的改变而发生变化,但是在实际情况中,往往有这样一种需求,我需要修改anchorPoint,但又不想要移动layer也就是不想修改frame.origin,那么根据前面的公式,就需要position做相应地修改。简单地推导,可以得到下面的公式:

positionNew.x= positionOld.x + (anchorPointNew.x - anchorPointOld.x) *bounds.size.width positionNew.y = positionOld.y + (anchorPointNew.y -anchorPointOld.y) * bounds.size.height

      但是在实际使用没必要这么麻烦。修改anchorPoint而不想移动layer,在修改anchorPoint后再重新设置一遍frame就可以达到目的,这时position就会自动进行相应的改变。写成函数就是下面这样的:

-(void)setAnchorPoint:(CGPoint)anchorpointforView:(UIView*)view{ CGRectoldFrame=view; view.layer.anchorPoint= anchorpoint; view.frame= oldFrame; }


总结

   1positionlayer中的anchorPointsuperLayer中的位置坐标.

   2、互不影响原则:单独修改positionanchorPoint中任何一个属性都不影响另一个属性。   

   3framepositionanchorPoint有以下关系:

frame.origin.x = position.x - anchorPoint.x *bounds.size.width; frame.origin.y = position.y - anchorPoint.y *bounds.size.height;

0 0
原创粉丝点击