iOS

position与anchorPoint

2017-08-16  本文已影响6人  大豆豆_小豆豆

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

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

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

然后再来看下面两张图,注意图中分iOS与MacOS,因为两者的坐标系不相同,iOS坐标原点在左上角,MacOS坐标原点在左下角,我们看iOS部分即可。

在上面这张图中,anchorPoint有(0.5,0.5)和(0,0)两种情况,分别为矩形的中心点与原点。那么,这两个anchorPoint在superLayer中的实际位置分别为多少呢?简单计算一下就可以得到(100, 100)和(40, 60),把这两个值分别与各自的position值比较,发现完全一致,该不会是巧合?

这时候可以大胆猜测一下,position是不是就是anchorPoint在superLayer中的位置呢?答案是确定的,更确切地说,position是layer中的anchorPoint点在superLayer中的位置坐标。因此可以说, position点是相对suerLayer的,anchorPoint点是相对layer的,两者是相对不同的坐标空间的一个重合点。

再来看看position的原始定义:

The layer’s position in its superlayer’s coordinate space。

中文可以理解成为position是layer相对superLayer坐标空间的位置。所以请记住这个结论:position的位置是根据anchorPoint来确定的。

anchorPoint通常被翻译成锚点,其实可以理解为同一个东西。它具体的表现可以看下面这张图,其实就是作为旋转、缩放等空间变化提供了中心点。这就类似于刚才讲的图钉订在白纸的正中间与左上角时分别造就了两种旋转形态。

3.anchorPoint、position、frame之间的关系

3.1 —— 三者之间的计算公式

聪明的你其实已经可以在第二点中已经找到这三者之间的关系了,现在我只不过是特地拿出来正式讲一下。

anchorPoint的默认值为(0.5,0.5),也就是anchorPoint默认在layer的中心点。计算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;

3.2 —— 第二个问题

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

**根据代码测试,两者互不影响,受影响的只会是frame.origin。**

所以我们又可以得出今天的第二个结论:anchorPoint和position互不影响,故受影响的只有frame。

现在又可以得出一个换汤不换药的装逼公式:

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

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

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

3.3 —— 优化

在实际情况中,可能还有这样一种需求,我需要修改anchorPoint而不想移动layer,在修改anchorPoint后再重新设置一遍frame就可以达到目的,这时position就会自动进行相应的改变。

代码:

- (void) setAnchorPoint:(CGPoint)anchorpoint forView:(UIView *)view{

CGRect oldFrame = view.frame;

view.layer.anchorPoint = anchorpoint;

view.frame = oldFrame;

}

总结

1、position是layer中的anchorPoint在superLayer中的位置坐标。

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

3、frame、position与anchorPoint有以下关系:

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

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

上一篇下一篇

猜你喜欢

热点阅读