为什么我的视图会在更改其anchorPoint后设置其帧时移动?

时间:2012-08-31 03:04:53

标签: objective-c ios uikit

我制作了UILabel的两个实例,并将它们添加到ViewController的视图中。 然后我将每个anchorPoint从0.5更改为1.0(x和y)。

接下来,我将uiLabel2的帧重置为我创建的帧:(100,100,100,20)。

当我运行应用时,uiLabel1uiLabel2显示在不同的位置。为什么呢?

UILabel *uiLabel1 = [[[UILabel alloc] initWithFrame:CGRectMake(100, 100, 100, 20)] autorelease];
uiLabel1.text = @"UILabel1";
uiLabel1.layer.anchorPoint = CGPointMake(1, 1);

UILabel *uiLabel2 = [[[UILabel alloc] initWithFrame:CGRectMake(100, 100, 100, 20)] autorelease];
uiLabel2.text = @"UILabel2";
uiLabel2.layer.anchorPoint = CGPointMake(1, 1);
uiLabel2.frame = CGRectMake(100, 100, 100, 20);

[self.view addSubview:uiLabel1];
[self.view addSubview:uiLabel2];

enter image description here

2 个答案:

答案 0 :(得分:42)

CALayer有四个属性可确定它在超级图层中的显示位置:

  • position(与视图的center属性相同)
  • bounds(实际上只有size的{​​{1}}部分)
  • bounds
  • anchorPoint

您会注意到transform 其中一个属性。 frame属性实际上是从这些属性派生的。设置frame属性后,该图层会根据您提供的框架和图层的现有frame实际更改其centerbounds.size

您创建第一个图层(通过创建第一个anchorPoint,它是UILabel的子类,每个UIView都有一个图层),给它一个100,100,100,20的帧。该图层的默认锚点为0.5,0.5。因此它计算其边界为0,0,100,20,其位置为150,110。它看起来像这样:

anchor at center

然后将其锚点更改为1,1。由于您不直接更改图层的位置或边界,并且您不通过设置其框架间接更改它们,因此图层会移动,以使其新锚点位于其超级图层中的(未更改)位置:

anchor at corner

如果您现在要求提供图层(或视图)框架,您将获得50,90,100,20。

创建第二层(第二层UIView)时,在更改其锚点后,设置其帧。因此,图层会根据您提供的帧及其现有锚点计算新位置和边界:

anchor at corner with reset frame

如果您现在询问图层(或视图)的框架,您将获得您设置的框架,100,100,100,20。但是如果你要求它的位置(或视图的中心),你将获得200,120。

答案 1 :(得分:4)

这正是锚点的作用。在更改锚点之前,您要根据标签的中心设置框架。之后,您将根据右下角设置框架。

由于您只是为一个标签重置框架,因此根据新的锚点调整其框架,另一个停留在旧位置。

如果你想让它们在同一个点上,那么你需要在编辑锚点后重置它们的帧,或者根本不要重置锚点。

This guide详细介绍了锚点。