综述iOS视图的frame、bounds、center、position、anchorPosition等与位置、大小有关的属性

原创 2015年11月20日 18:08:21
       在iOS开发开发过程中经常会用到界面元素的frame、bounds表示大小和位置的属性以及center、position、anchorPosition等单纯表示位置的属性。这些属性究竟什么含义?彼此间又什么关系呢?下面就来浅谈一番。

首先来说说frame和bounds。

        frame:描述当前界面元素在其父界面元素中的位置和大小。
        bounds:描述当前界面元素在其自身坐标系统中的位置和大小。
        iOS以左上角为坐标原点(0,0),以原点向右侧为X轴正方向,原点下侧为Y轴正方向。iOS采用CGPoint来表示点在坐标系上X、Y位置。同时,iOS采用CGSize来表示界面元素的宽度和高度,即视图的大小。而CGRect则是结合了CGPoint和CGSize,用来表示矩形的位置和大小。它的origin表示矩形右上角所在位置(CGPoint),size表示矩形的大小(CGSize)。
        frame所描述的大小跟bounds所描述的大小是一致的,都是指界面元素的宽和高。但它们所描述的位置却不相同,frame描述的位置是指该界面元素左上角在父界面元素坐标系中的位置,而bounds描述的位置是指该界面元素左上角在自身坐标系中的位置,所以bounds描述的位置始终为(0,0)。可以说frame和bounds最大区别在于它们选取的坐标系不同。如下图:

                                                                 

下面再来说说center、position和anchorPosition三个单纯表示位置的属性。

        说这三个属性前得先了解下CALayer。
        UIView是iOS系统中界面元素的基础,所有的界面元素都是继承自它。它本身完全是由CoreAnimation来实现的。它真正的绘图部分,是由一个CALayer类来管理。UIView本身更像是一个CALayer的管理器,访问它的跟绘图和跟坐标有关的属性,例如frame,bounds等,实际上内部都是在访问它所包含的CALayer的相关属性。
       center:描述当前界面元素的中心点在其父界面元素中的位置。center只能通过界面元素本身访问,而CALayer没有提供外部访问的该属性,但通过前面的描述可以知道,访问界面元素的center属性肯定也是调用了CALayer的相关属性计算得出的。一般我们可以通过下面的计算得出center。


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

       不过通常我们用不到这样的计算。
       接下来重点说说其它两个描述位置的属性position和anchorPosition。
  

    @property CGPoint position
    @property CGPoint anchorPoint

       通过声明我们可以发现它们都是CGPoint类型。此刻我们把CALayer看作是一张打印纸被一根图钉钉在桌面上(相当于父界面元素的CALayer),可以想像这张打印纸可以绕着这根图钉旋转。那么图钉相对于打印纸的位置就可以用anchorPosition来描述,而这根图钉在桌面上的位置便是position。
      在iOS中,anchorPoint点的值是用一种相对bounds的比例值来确定的,在打印纸的左上角、右下角,anchorPoint分别为(0,0), (1, 1),也就是说anchorPoint是在单元坐标空间(同时也是左手坐标系)中定义的。类似地,可以得出在打印纸纸的中心点、左下角和右上角的anchorPoint为(0.5,0.5), (0,1), (1,0)。请参考下图,注意图中分iOS与MacOS,因为两者的坐标系不相同,iOS使用左手坐标系,坐标原点在左上角,MacOS使用右手坐标系,原点在左下角,我们看iOS部分即可。

                                                                    

        再来看看position的原始定义: The layer’s position in its superlayer’s coordinate space。中文可以理解成为position是layer相对superLayer坐标空间的位置,很显然,这里的位置是根据anchorPoint来确定的。 至于如何确定,请看下面的公式。
  
  

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

       如果单方面修改layer的position位置,会对anchorPoint有什么影响呢?修改anchorPoint又如何影响position呢?
       虽然说Position是根据anchorPosition来确定的,但根据代码测试,两者互不影响,受影响的只会是frame.origin,也就是layer坐标原点相对superLayer会有所改变。换句话说,frame.origin由position和anchorPoint共同决定,上面的公式可以变换成下面这样的。
  
   
    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。
        Apple doc中还有一句描述是这样的:
 
        When you specify the frame of a layer, position is set relative to the anchor point. When you specify the position of the layer, bounds is set relative to the anchor point.
 
       当你设置图层的frame属性的时候,position点的位置(也就是position坐标)根据锚点(anchorPoint)的值来确定,而当你设置图层的position属性的时候,bounds的位置(也就是frame的orgin坐标)会根据锚点(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)anchorpoint forView:(UIView *)view{
       CGRect oldFrame = view.frame;
       view.layer.anchorPoint = anchorpoint;
       view.frame = oldFrame;
    }



以上内容是本人结合开发经验并参考了部分资料而撰写的,如有不妥之处还请不吝赐教,愿大家能够互相学习,共同进步。

版权声明:本文为博主原创文章,未经博主允许不得转载。

锚点(Anchor)和位置(Position)

在cocos2d-x中锚点位置对于新手来说总会有点难理解。以下是我对其的一点理解。         在每个spirit中 都会有一个锚点和位置。锚点是用来描述比例用的所以它的大小在0~1之间,在等比放...
  • qw503495315
  • qw503495315
  • 2013年07月23日 20:44
  • 1763

ios-坐标系统(详解UIView的frame、bounds跟center属性[图])

1、概要 翻开ios官方开发文档,赫然发现上面对这三个属性的解释如下: frame:描述当前视图在其父视图中的位置和大小。 bounds:描述当前视图在其自身坐标系统中的位置和大小。 ce...
  • cheneystudy
  • cheneystudy
  • 2012年10月26日 15:19
  • 22271

ios开发讲解之anchorPoint和position详解

引言         相信初接触到CALayer的人都会遇到以下几个问题:  为什么修改anchorPoint会移动layer的位置?CALayer的position点是哪一点呢? anch...
  • webparrot
  • webparrot
  • 2016年08月10日 15:43
  • 200

ios-anchorPoint、position理解

anchorPoint(锚点)是 layer的一个属性,下面我们来看看其对view的影响,本文主要通过图片方式展现: 锚点用单位坐标来描述也就是图层的相对坐标。在苹果文档中说明左下是(0,0),右上是...
  • zyzxrj
  • zyzxrj
  • 2016年08月05日 17:29
  • 931

ios CALayer的Frame,bounds,position,anchorPoint

记录四者之间的关系* frame.origin.x = position.x - anchorPoint.x bounds.size.width; ** * frame.origin.y = ...
  • ifdefine
  • ifdefine
  • 2016年04月13日 20:35
  • 476

详解UIView的frame、bounds和center属性

1、概要 翻开ios官方开发文档,赫然发现上面对这三个属性的解释如下: frame:描述当前视图在其父视图中的位置和大小。 bounds:描述当前视图在其自身坐标系统中的位置和大小。...
  • muyu114
  • muyu114
  • 2012年04月06日 10:15
  • 10224

iOS - tabbar的titlePositionAdjustment

设置tabbar的item的文字的时有个属性 titlePositionAdjustment 先看一个结构体:typedef struct UIOffset { C...
  • Sir_Coding
  • Sir_Coding
  • 2017年04月09日 19:31
  • 1446

CALayer中anchorPoint和position的用法

每当修改一个CALayer的anchorPoint属性时,都要重新设置CALayer的position坐标 1.CALayer *layer = [myView layer]; 2.[la...
  • primer_programer
  • primer_programer
  • 2013年08月11日 20:25
  • 12020

ios 通过设置UI控件的center和size来设置位置时需注意!

今天在设置按钮位置时,使用center和size属性来控制,但是发现怎么也不对,研究了一下发现,当使用UI控件的center和size属性来控制位置时,好像是有先后顺序的: 下面看一段代码,将红色的v...
  • Make___
  • Make___
  • 2015年06月17日 15:42
  • 5021

iOS开发总结之 view的frame、center和和view的bounds之间的区别

iOS开发总结之 view的frame、center和和view的bounds之间的区别
  • sunnyboy9
  • sunnyboy9
  • 2016年04月28日 21:23
  • 397
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:综述iOS视图的frame、bounds、center、position、anchorPosition等与位置、大小有关的属性
举报原因:
原因补充:

(最多只允许输入30个字)