frame: 该view在父view坐标系统中的位置和大小。(参照点是,父亲的坐标系统)
bounds:该view在本地坐标系统中的位置和大小。(参照点是,本地坐标系统,就相当于view自己的坐标系统,以0,0点为起点)。
其实本地坐标系统的关键就是要知道的它的原点(0,0)在父坐标系统中的什么位置(这个位置是相对于父view的本地坐标系统而言的,最终的父view就是UIWindow,它的本地坐标系统原点就是屏幕的左上角了)。
通过修改view的bounds属性可以修改本地坐标系统的原点位置。
frame我相信大家都理解的比较清楚,但是bounds光是这么说估计大家都很迷糊,那么我们下面来看具体的实例。
一、常规的场景
//创建红色view
UIView *redView = [[UIView alloc] initWithFrame:CGRectMake(100, 100, 200, 200)];
NSLog(@"log1:%@",NSStringFromCGRect(redView.frame));
redView.backgroundColor = [UIColor redColor];
//把红色view添加到控制器view上
[self.view addSubview:redView];
//创建紫色view
UIView *purpleView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 80, 80)];
purpleView.backgroundColor = [UIColor purpleColor];
NSLog(@"log2:%@",NSStringFromCGRect(purpleView.frame));
//把紫色view添加到红色view上
[redView addSubview:purpleView];
输出日志:
2019-02-19 18:15:35.906877+0800 FMDBTest[16308:790296] log1:redView frame:{{100, 100}, {200, 200}}========redView bounds:{{0, 0}, {200, 200}}
2019-02-19 18:15:35.907117+0800 FMDBTest[16308:790296] log2:purpleView frame:{{0, 0}, {80, 80}}========redView bounds:{{0, 0}, {80, 80}}
二、改变redView的bounds的x和y
//设置bounds,x,y分别为20,20,宽高不变
redView.bounds = CGRectMake(20, 20, 200, 200);
输出日志:
2019-02-19 18:27:46.299382+0800 FMDBTest[16523:799583] log1:redView frame:{{100, 100}, {200, 200}}========redView bounds:{{0, 0}, {200, 200}}
2019-02-19 18:27:46.299552+0800 FMDBTest[16523:799583] log2:redView frame:{{100, 100}, {200, 200}}========redView bounds:{{20, 20}, {200, 200}}
2019-02-19 18:27:46.299723+0800 FMDBTest[16523:799583] log3:purpleView frame:{{0, 0}, {80, 80}}========redView bounds:{{0, 0}, {80, 80}}
分析
- 上面设置redView的bounds的代码起到了让purpleView的位置改变的作用。为何(20,20)的偏移量,却可以让purpleView向左上角移动呢?
- 这是因为setBounds的作用是:强制将自己(redView)本地坐标系的原点改为(20,20)。这个(20,20))是相对redView的父view(self.view)偏移的。也就是向右下角偏移。
- 那么在redView的坐标系中(0,0)这个点是需要向左上各偏移20。
- 因为redView的subview(purpleView)的frame参照的坐标系是父view(redView)的bounds设置的,而此时purpleView的frame设置为(0,0),就会导致purpleView向左上各偏移20。如上图所示。
三、上面只是改变了bounds的x和y,若width和height也改呢
redView.bounds = CGRectMake(20, 20, 300, 300);
输出日志:
2019-02-19 18:26:43.545989+0800 FMDBTest[16496:798558] log1:redView frame:{{100, 100}, {200, 200}}========redView bounds:{{0, 0}, {200, 200}}
2019-02-19 18:26:43.546154+0800 FMDBTest[16496:798558] log2:redView frame:{{50, 50}, {300, 300}}========redView bounds:{{20, 20}, {300, 300}}
2019-02-19 18:26:43.546293+0800 FMDBTest[16496:798558] log3:purpleView frame:{{0, 0}, {80, 80}}========redView bounds:{{0, 0}, {80, 80}}
- 我们会发现:review的frame不仅width、height变了,x,y也变了,从之前的(100,100),变成了(50,50),x、y都减少了50。
- 由此我们知道,改变bounds的width和height,不仅会影响frame的width和height(两者的width和height保持一致),还会影响frame的x,y。这种影响是随着bounds的width和height增加或减少,平均扩充或缩减四周的区域。
- 用上面的例子解释,bounds宽高都增加了100,所以会向四周平均扩充区域,在原来的基础上,往上、往下、往左、往右各扩充50,所以x、y都会减少50。
四、总结
bounds的有以下两个特点:
1. 它可以修改自己坐标系的原点位置,影响“子view”的显示位置。
2. bounds,它可以通过改变宽高,改变自身的frame,进而影响到再父视图的显示位置和大小。