UIView 中 frame 和 bounds 的区别和关系

2018-10-17  本文已影响12人  Headwindx

UIView 中 frame 和 bounds 的区别和关系

区别

首先说说区别, 根据官方描述我们知道 frame 描述了该视图与父视图之间的平面坐标和大小;bounds 描述了该视图内部可见区域的坐标和大小。

但是仅仅靠这句简单的话,很难有直观的理解,我们心中会有千万个疑问,其中一定有一个 : frame 既然表示了视图的大小和坐标,还他妈要 bounds 何用?

我们下面慢慢展开,通过简单的几行代码,一步步发现其中缘由。

二者的关系

这里还要交代一下,UIView 和 CALayer 的 frame 以及 bounds 是同一个概念,UIView 是 CALayer 的代理,以及几何对等体,简单说,在 frame 和 bounds的层面,我们可以认为 UIView 和 CALayer 完全相同。暂时忽略掉 CALayer 。

frame.size.width = bounds.size.height * scaleX;
frame.size.height = bounds.size.height * scaleY;

我们可以通过代码来验证以上结论:

UIView *a = [UIView new];
a.frame = (CGRect){0, 0, 300, 300);
NSLog(@"a frame : %@, bounds :%@", NSStringFromCGRect(a.frame), NSStringFromCGRect(a.bounds));

CGFloat scaleFactor = 2.0;
a.layer.affineTransform = CGAffineTransformScale(a.layer.affineTransform, scaleFactor, scaleFactor);

NSLog(@"a frame : %@, bounds :%@", NSStringFromCGRect(a.frame), NSStringFromCGRect(a.bounds));

输出结果为:

a frame : {{100, 100}, {150, 150}}, bounds :{{-50, -50}, {150, 150}}

a frame : {{100, 100}, {300, 300}}, bounds :{{-50, -50}, {150, 150}}

第一行输出,由于未进行缩放,缩放因子为 1.0,因此 frame 和 bounds 大小一致。
第二行输出,由于进行了缩放,缩放银子为 2.0,因此 frame 的宽高是 bounds 的一倍。

由此验证结论的正确性。

解读 UIView 和 CALayer

CALayer 负责 UIView 的支持层,主要管理视觉内容,比如:背景色,边框,阴影。还有视图的几何信息,比如:大小,位置以及变形。通过 CAMediaTiming 协议,封装了动画时间和空间相关的信息。

从 UIView 和 CALayer 之间的关系,以及 frame 和 bounds 的关系,可以得出以下结论:

frame 是 View 投影到 Screen 上的投影大小,也是我们看到的大小,而 bounds 为 View 的实际大小。

如果说 View 是一个黑箱,那么 bounds 是这个黑箱上的一个开口(窗口),窗口的大小,直接决定了能看到的区域和大小,而 frame 则是我们的屏幕,从黑箱中射出来的光线,直接投影到屏幕上。

在投影的过程中,通过透镜调节,可以控制投影到屏幕上的大小,这个透镜就是 UIView.transform,用数学公式可以表示为: frame = transform x bounds 这里是矩阵叉程。

由此,可以知道 bounds 的坐标,相当于坐标系的原点,这样就和平面解析几何关联上了。修改 bounds 的坐标,就是坐标平移。

到这里,我想 frame 和 bounds 之间的关系已经很清晰了。

上一篇下一篇

猜你喜欢

热点阅读