我想知道如何以正确的方式使用这些属性 .
据我所知, frame
可以从我正在创建的视图的容器中使用 . 它设置相对于容器视图的视图位置 . 它还设置该视图的大小 .
也可以从我正在创建的视图的容器中使用 center
. 此属性更改视图相对于其容器的位置 .
最后, bounds
与视图本身相关 . 它会更改视图的可绘制区域 .
你能否提供更多关于 frame
和 bounds
之间关系的信息? clipsToBounds
和 masksToBounds
属性怎么样?
6 回答
我想如果你从
CALayer
的角度来看,一切都更清楚了 .Frame is not really a distinct property of the view or layer at all, it is a virtual property, computed from the bounds, position(UIView's center), and transform.
所以基本上如何通过这三个属性(和anchorPoint)真正决定图层/视图布局,并且这三个属性中的任何一个都不会更改任何其他属性,例如更改变换不会更改边界 .
这篇文章的详细解释有很好的答案 . 我只是想提一下,在WWDC 2011视频 Understanding UIKit Rendering 从@ 4:22到20:10开始,有关于Frame,Bounds,Center,Transform,Bounds Origin的含义的视觉表示的另一种解释
由于我问过的问题已多次出现,我将提供详细的答案 . 如果您想添加更多正确的内容,请随意修改它 .
首先回顾一下这个问题:框架,界限和中心以及他们之间的关系 .
Frame 视图的
frame
(CGRect
)是其矩形在superview
坐标系中的位置 . 默认情况下,它从左上角开始 .Bounds 视图的
bounds
(CGRect
)在其自己的坐标系中表示视图矩形 .Center A
center
是CGPoint
,以superview
的坐标系表示,它确定了视图精确中心点的位置 .取自 UIView + position ,这些是之前属性中的关系(它们在代码中不起作用,因为它们是非正式方程式):
frame.origin = center - (bounds.size / 2.0)
center = frame.origin + (bounds.size / 2.0)
frame.size = bounds.size
NOTE: 如果轮换视图,则这些关系不适用 . 有关详细信息,我建议您根据 Stanford CS193p 课程查看从 The Kitchen Drawer 拍摄的以下图像 . 积分转到 @Rhubarb .
使用
frame
允许您在superview
中重新定位和/或调整视图大小 . 通常可以在superview
中使用,例如,在创建特定子视图时 . 例如:当您需要在
view
内绘制坐标时,通常会引用bounds
. 一个典型的例子可能是在第一个插图中插入一个子视图 . 绘制子视图需要知道superview的bounds
. 例如:更改视图的
bounds
时会发生不同的行为 . 例如,如果更改bounds
size
,则frame
会更改(反之亦然) . 更改发生在视图的center
周围 . 使用下面的代码,看看会发生什么:此外,如果更改
bounds
origin
,则更改其内部坐标系的origin
. 默认情况下,origin
位于(0.0, 0.0)
(左上角) . 例如,如果更改origin
forview1
,您可以看到(如果需要,请注释前面的代码),现在view2
的左上角触及了view1
. 动机很简单 . 你对view1
说它的左上角现在位于(20.0, 20.0)
位置,但是自view2
的frame
origin
从(20.0, 20.0)
开始,它们将重合 .origin
表示view
在superview
中的位置,但描述了bounds
中心的位置 .最后,
bounds
和origin
不是相关的概念 . 两者都允许导出视图的frame
(参见前面的等式) .View1的案例研究
以下是使用以下代码段时发生的情况 .
相对的形象 .
相反,如果我改变如下的
[self view]
界限会发生什么 .相对的形象 .
在这里你说
[self view]
它的左上角现在位于(30.0,20.0)位置,但由于view1
的帧起点从(30.0,20.0)开始,它们将重合 .Additional references (如果需要,可以使用其他参考资料更新)
UIView Geometry
UIView Frames and Bounds
关于
clipsToBounds
(来源Apple doc)换句话说,如果视图的
frame
是(0, 0, 100, 100)
且其子视图是(90, 90, 30, 30)
,您将只看到该子视图的一部分 . 后者不会超过父视图的范围 .masksToBounds
相当于clipsToBounds
. 而不是UIView
,此属性应用于CALayer
. 引擎盖下,clipsToBounds
调用masksToBounds
. 如需进一步参考,请查看How is the relation between UIView's clipsToBounds and CALayer's masksToBounds? .这个问题已经有了一个很好的答案,但我想补充一些更多的图片 . My full answer is here.
为了帮助我记住 frame ,我想起了 a picture frame on a wall . 就像图片可以移动到墙上的任何地方一样,视图框架的坐标系是超视图 . (wall = superview,frame = view)
为了帮助我记住 bounds ,我想起了 the bounds of a basketball court . 篮球就在球场内的某个地方,就像视线边界的坐标系在视野内一样 . (法庭=视图,篮球/球员=视图内的内容)
像框架一样, view.center 也在superview的坐标中 .
框架与边界 - 示例1
黄色矩形表示视图的框架 . 绿色矩形表示视图的边界 . 两个图像中的红点表示框架的原点或其坐标系内的边界 .
示例2
示例3
示例4
这与示例2相同,除了这次显示视图的整个内容,如果它没有被剪切到视图的边界,它将看起来像 .
例5
再次,请参阅here以获取更多详细信息 .
我发现这个图像对于理解框架,边界等最有帮助 .
另请注意图像旋转时的
frame.size != bounds.size
.阅读完上述答案后,在此添加我的解释 .
假设在线浏览, web browser 是您的
frame
,它决定了显示网页的位置和大小 . 浏览器的 Scroller 是您的bounds.origin
,它决定了哪个部分的网页会被显示 .bounds.origin
很难理解 . 学习的最佳方法是创建单视图应用程序,尝试修改这些参数并查看子视图的更改方式 .