本文档是对培训文档
Frame和Bounds.pdf的补充,基本概念略过。
本文档描述Bounds的origin变化,引起的子视图位置移动的过程以及原理。
这里还未探究当旋转缩放等用到矩阵转换时,frame的size与bounds的size不一致的情况。
预设
- 预设三种View,
SuperView、CurrentView以及SubView - 统一概念,
SuperView的坐标系,称为世界坐标系,具体就是frame使用的坐标系。 - 统一概念,
CurrentView的坐标系,称为本地坐标系,具体就是bounds使用的坐标系。
参照系
- 世界坐标系,影响的
CurrentView的显示位置也即本地坐标系的位置,frame改变的是CurrentView的世界坐标系的位置(绝对位置)。 - 本地坐标系,影响的是
SubView的显示位置。因为本地坐标系是SubView的世界坐标系,bounds修改本地坐标系的坐标原点,但是本地坐标系的位置并没有改变(frame控制)。
依据
- 已知
SetBounds之后,系统会进行光栅化处理,把视图展示在屏幕上。可以根据最终视图的显示推理相应原理。
DEMO为例
黄色View是一个ScrollView,1,2,3是三个UIImageView.
通常看到的效果

028.gif
设置
sv.layer.masksToBounds = NO;

029.gif
分析
品红色为
SuperView,黄色SCrollView为CurrentView,1,2,3标号的为3个SubView.
绿色坐标系为CurrentView的世界坐标系,蓝色坐标系为CurrentView的本地坐标系
初始状态

截屏2016_12_28_下午1_58.png
上滑之后

iPhone_6s_-_iPhone_6s___iOS_9_3__13E230_.png
对比两种状态
-
CurrentView的frame没有改变,CurrentView的本地坐标系的位置也没有变,只有本地坐标系的原点的值变了。 -
原点y值由0变为128,SubView①图的frame的origin是(0,0)没变,则在y坐标原点的负方向找到y值为0的地方,移动到对应(0,0)的位置。视觉效果就是向上滚动,超过默认的可视区域。
结论
- 要改变
CurrentView的位置,有两种方法。
- 改变
CurrentView的Frame(改变自己) - 改变
SuperView的Bounds(改变参照物)
-
CurrentView的Bounds改变Origin是更新了本地坐标系原点的值,但并没有改变本地坐标系的位置(蓝色坐标系未动)。坐标原点作为SubView的参照物,参照物改变,SubView的frame没有变,造成SubView在CurrentView中绝对位置的移动。
通俗地讲:
frame调整自己的位置大小,bounds调整子视图的位置大小
旋转等矩阵操作是对世界坐标进行变换,影响到frame的改变,从而改变当前视图的大小位置等。
Demo
TSScrollViewDemogit地址。