相信你们学习iOS视图部分的时候,跟它俩没少纠缠,尤为是bounds不少朋友都糊了,bounds确实比较难理解。这两个概念很重要,由于它们是奠基整个视图层次结构的基础。因此咱们须要了解的透彻一点。源代码git
首先,咱们来看一下iOS特有的坐标系,在iOS坐标系中以左上角为坐标原点,往右为X正方向,往下是Y正方向以下图:github
bounds和frame都是属于CGRect类型的结构体,系统的定义以下,包含一个CGPoint(起点)和一个CGSize(尺寸)子结构体。学习
struct CGRect {
CGPoint origin;
CGSize size;
};
复制代码
origin决定了view的起点,size决定View的尺寸。spa
frame是每一个view必备的属性,表示view在父view坐标系统中的位置和大小,参照点是父视图的坐标系统。code
示例代码:cdn
UIView *viewA = [[UIView alloc] initWithFrame:CGRectMake(50, 50, 300, 300)];
[viewA setBackgroundColor:[UIColor blueColor]];
[self.view addSubview:viewA];
NSLog(@"viewA - %@",NSStringFromCGRect(viewA.frame));
UIView *viewB = [[UIView alloc] initWithFrame:CGRectMake(50, 50, 200, 200)];
[viewB setBackgroundColor:[UIColor yellowColor]];
[viewA addSubview:viewB];
NSLog(@"viewB - %@",NSStringFromCGRect(viewB.frame));
UIView *viewC = [[UIView alloc] initWithFrame:CGRectMake(100, 100, 100, 100)];
[viewC setBackgroundColor:[UIColor redColor]];
[self.view addSubview:viewC];
NSLog(@"viewC - %@",NSStringFromCGRect(viewC.frame));
复制代码
打印结果:blog
2018-01-14 21:35:16.196389+0800 frame & bounds[1485:121325] viewA - {{50, 50}, {300, 300}}
2018-01-14 21:35:16.196647+0800 frame & bounds[1485:121325] viewB - {{50, 50}, {200, 200}}
2018-01-14 21:35:16.196802+0800 frame & bounds[1485:121325] viewC - {{100, 100}, {200, 200}}
复制代码
效果图:get
以上能够看出,viewB和viewC的起点重合,可是从打印结果来看,viewB的起点为(50,50),而viewCde起点为(100,100)。缘由就是frame中的位置是以父视图的坐标系为标准来肯定当前视图的位置,viewB的父视图为viewA,viewC的父视图为self.view,而因为viewA的起点为(50,50),因此viewB与viewC起点才会重合。it
bounds也是每一个view都有的属性,这个属性咱们通常不进行设置,表示view在本地坐标系统中的位置和大小。参照点是本地坐标系统。若是咱们对上例打印bounds,将会获得如下结果:io
2018-01-14 22:03:44.385207+0800 frame & bounds[1635:140821] viewA - {{0, 0}, {300, 300}}
2018-01-14 22:03:44.385482+0800 frame & bounds[1635:140821] viewB - {{0, 0}, {200, 200}}
2018-01-14 22:03:44.385646+0800 frame & bounds[1635:140821] viewC - {{0, 0}, {100, 100}}
复制代码
由于咱们并无设置bounds值,那么,bounds到底有什么做用呢。这里强调,每一个视图都有本身的坐标系,且这个坐标系默认以自身的左上角为坐标原点,全部子视图以这个坐标系的原点为基准点。bounds的位置表明的是子视图看待当前视图左上角的位置,bounds的大小表明当前视图的大小。原则以下:
如下给出例子详细讨论。
以下图:
此时,若是咱们把ViewA的bounds改成(0,100),结果以下:
咱们始终要清楚,bounds的位置表明的是子视图看待当前视图左上角的位置。 bounds遵照的原则一中,更改bounds中的位置对于当前视图(ViewA)没有影响,至关于更改了ViewA的坐标系,可是子视图(ViewB)不一样,对于ViewB来讲ViewA的左上角已经再也不是(0,0), 而是(0,100),因此对于ViewB来讲,ViewA坐标系的原点实际上是在红色箭头所指处的上方100处,而此时ViewB的frame.origin为(200,100),因此ViewB的上边与ViewA上边重合。
若是咱们更改ViewA的bounds为(200,0),同理(能够本身思考试试),结果以下:
frame的size直接决定了view的大小,而bounds的size修改后,view的中心点不变,长宽以中心点进行缩放。
以下例:
UIView *viewA = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 240)];
[viewA setBackgroundColor:[UIColor grayColor]];
[self.view addSubview:viewA];
UIView *viewB = [[UIView alloc] initWithFrame:CGRectMake(100, 50, 160, 120)];
[viewB setBackgroundColor:[UIColor blueColor]];
[viewA addSubview:viewB];
//viewB设置size(320,160)
[viewB setBounds:CGRectMake(0, 0, 320, 240)];
复制代码
结果以下:
第二个图为设置了size以后的结果,viewB左上点距离viewA显然不为(100,50),而是进行了基于viewB视图中心点的缩放操做。