frame
frame 是每个 view 必备的属性,代表的是当前视图的位置和大小,如果没有设置该属性,当前视图是看不到的。
位置需要有参照物才能确定,数学中我们用坐标系来确定坐标系中的某个点的位置,IOS 中有他特有的坐标系:
- 在 IOS 坐标系中以左上角为坐标原点,往右为正 X 方向,往下为正 Y 方向;
- frame 中的位置是以父视图的坐标系为你标准来确定当前视图的位置;
- 同样的默认情况下,本视图的左上角就是子视图的坐标原点;
- 更改 frame 中位置,则当前视图的位置会发生改变;
- 更改 frame 的大小,则当前视图以当前视图的左上角为基准进行大小的修改。
bounds
bounds 是每个 View 都有的属性,这个属性我们一般不进行设置,他同样代表位置和大小;
每个视图都有自己的坐标系,且这个坐标系默认以自身的左上角为坐标原点,所有子视图以这个坐标系的原点为基准点;
bounds 的位置代表的是子视图看待当前视图左上角的位置,bounds 的大小代表当前视图的大小;
更改 bounds 中的位置对于当前视图没有影响,相当于更改了当前视图的坐标系,对于子视图来说当前视图的左上角已经不再是(0,0), 而是改变后的坐标,坐标系改了,那么所有子视图的位置也会跟着改变;
更改 bounds 的大小,bounds 的大小代表当前视图的长和宽,修改长宽后,中心点继续保持不变, 长宽进行改变;通过 bounds 修改长宽看起来就像是以中心点为基准点对长宽两边同时进行缩放;
矩形框和内容的理解
矩形框(当前视图):即控件自身显示的位置和尺寸;
内容(当前视图的子视图):控件内部的东西;
概括来说,frame以“父控件”“内容”的左上角为坐标原点,计算出的“控件自己”“矩形框”的尺寸;
bounds以“控件自己”“内容“的左上角为坐标原点,计算出的”控件自己“”矩形框“的位置和尺寸;
有如下总结:
frame.size == bounds.size;
scrollView.bounds.origin == scrollView.contentOffset;
下面以实例演示:
点击屏幕后:
也许会奇怪,为何设置了 redView 的 bounds 为(-50,-50),开关控件反而向右下方移动了?
这里作出解释:redView 的 bounds 发生了改变,则其子视图(开关控件)的原点发生了改变,而 redView 的 frame 是固定不动的,即 redView 的位置和尺寸是不会变化的,所以唯有子控件(开关控件)的位置发生改变,即内容发生偏移,相当于矩形框相对内容原点偏移(-50,-50)。
最后,用一个图总结一下 bounds 与 frame 的区别与意义: