为什么在UIView中有一个frame矩形和一个bounds矩形?

43
虽然已经深夜了,但我还是不明白为什么会有两个不同的矩形:frame和bounds。
我理解的是,一个单独的矩形应该足够完成所有的事情。将视图本身相对于另一个坐标系统进行定位,并将其内容裁剪到指定的大小。你还能用两个矩形做什么呢?它们之间如何相互作用?
有人能给个好的解释吗?苹果文档中那个拿着水果的孩子的解释并不容易理解。
3个回答

84

这是速查表:

  • frame是视图相对于父视图的位置。
  • bounds是视图允许绘制的区域,相对于自身。

以下是更多解释:

如果你要在父视图中定位视图,几乎总是更改frame原点。

如果你要裁剪UIView绘制的区域,几乎总是修改它的bounds。

请注意,bounds可以比frame更大。 这意味着你可以在规定的范围之外画出内容。


因此,该框架类似于相对于父视图坐标系统的起始坐标,从该起始点开始,边界剪切将在相对于视图坐标系统的坐标中进行? - Thanks
我注意到范围始终具有0,0的起点。因此,边界始终从0开始。我是正确的吗? - user4951
通常边界的起点是0,0。但并不一定非得这样。 - amattn
1
bounds 是视图允许绘制的区域(相对于自身),但仅当 clipsToBounds 为 NO 时才成立。 - jbat100
1
你真的能够使其中一个比另一个更大吗?文档中说:“边界矩形的大小与框架矩形的大小相耦合,因此对其中一个的更改会影响到另一个。” https://developer.apple.com/library/ios/documentation/uikit/reference/uiview_class/UIView/UIView.html#//apple_ref/occ/instp/UIView/bounds - bearMountain
边界不一定具有(0,0)原点。最好的例子可能是滚动视图:如果您想象一个可以垂直滚动的滚动视图,那么只有当它滚动到最顶部时,bounds.origin才等于(0,0)。 - sergey.n

5

Frame是相对于父视图的坐标系,而bounds是相对于本身视图的坐标系。在我看来,这两者都很方便。Frame似乎更有用,除非有一些我不知道的情况,即子视图可以具有完全不同的坐标系(例如,像素按不同比例缩放)。


1
如果更改子视图的变换属性,例如通过设置其旋转角度,其边界将保持不变,但其坐标系统将与父视图不同。 - jdc

2
我最近在处理边界问题时遇到了一些麻烦,并进行了一些实验。bounds属性确实限制了UIView的绘制范围,但不会限制它的子视图。bounds还控制着触摸事件的派发。据我所知,视图将不会接收到其边界之外的触摸事件。此外,任何超出父视图边界的子视图也将无法接收到触摸事件。在这些情况下,您必须仔细地更新容器视图的边界,以使其子视图的大小和位置保持一致。由于子视图没有被父视图的边界剪裁,因此一切都会正常绘制,但是触摸事件将不会被接收。

(这应该是对先前帖子的回复,但由于我还不能回复,所以现在只能放在这里......)


3
UIView 有一个 clipsToBounds 属性,它可以防止其子视图超出边界绘制。 - amattn
如果你重写pointInside:withEvent方法,你可以截获视图范围之外的触摸事件。非常适合制作比实际尺寸更大的按钮。 - kubi
如果应用了变换,触摸事件是否会被转换回边界坐标系? - Sam

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接