Lor*_*o B 315 objective-c frame uiview bounds ios
我想知道如何以正确的方式使用这些属性.
据我所知,frame可以从我正在创建的视图的容器中使用.它设置相对于容器视图的视图位置.它还设置该视图的大小.
也center可以从我正在创建的视图的容器中使用.此属性更改视图相对于其容器的位置.
最后,bounds是相对于视图本身.它会更改视图的可绘制区域.
你能给约之间的关系更多信息frame和bounds?那些clipsToBounds和masksToBounds属性呢?
Lor*_*o B 570
由于我问过的问题已多次出现,我将提供详细的答案.如果您想添加更多正确的内容,请随意修改它.
首先回顾一下这个问题:框架,边界和中心以及它们之间的关系.
框架视图frame(CGRect)是其superview坐标系中矩形的位置.默认情况下,它从左上角开始.
边界视图bounds(CGRect)表示其自身坐标系中的视图矩形.
中心 A center是CGPoint用superview坐标系表示的,它决定了视图的精确中心点的位置.
从UIView +位置开始,这些是之前属性中的关系(它们在代码中不起作用,因为它们是非正式方程式):
frame.origin = center - (bounds.size / 2.0)
center = frame.origin + (bounds.size / 2.0)
frame.size = bounds.size
注意:如果旋转视图,则这些关系不适用.有关详细信息,我建议您查看以下基于斯坦福CS193p课程的厨房抽屉图片.积分归@Rhubarb所有.

使用frame允许您在其中重新定位和/或调整视图大小superview.通常可以从a中使用superview,例如,在创建特定子视图时.例如:
// view1 will be positioned at x = 30, y = 20 starting the top left corner of [self view]
// [self view] could be the view managed by a UIViewController
UIView* view1 = [[UIView alloc] initWithFrame:CGRectMake(30.0f, 20.0f, 400.0f, 400.0f)];
view1.backgroundColor = [UIColor redColor];
[[self view] addSubview:view1];
Run Code Online (Sandbox Code Playgroud)
当你需要在里面绘制坐标时,view你通常会参考bounds.一个典型的例子可能是在view子视图中绘制第一个插图.绘制子视图需要知道超bounds视图.例如:
UIView* view1 = [[UIView alloc] initWithFrame:CGRectMake(50.0f, 50.0f, 400.0f, 400.0f)];
view1.backgroundColor = [UIColor redColor];
UIView* view2 = [[UIView alloc] initWithFrame:CGRectInset(view1.bounds, 20.0f, 20.0f)];
view2.backgroundColor = [UIColor yellowColor];
[view1 addSubview:view2];
Run Code Online (Sandbox Code Playgroud)
更改bounds视图时会发生不同的行为.例如,如果更改bounds size,则frame更改(反之亦然).变化发生在center视图周围.使用下面的代码,看看会发生什么:
NSLog(@"Old Frame %@", NSStringFromCGRect(view2.frame));
NSLog(@"Old Center %@", NSStringFromCGPoint(view2.center));
CGRect frame = view2.bounds;
frame.size.height += 20.0f;
frame.size.width += 20.0f;
view2.bounds = frame;
NSLog(@"New Frame %@", NSStringFromCGRect(view2.frame));
NSLog(@"New Center %@", NSStringFromCGPoint(view2.center));
Run Code Online (Sandbox Code Playgroud)
此外,如果你改变bounds origin你改变origin它的内部坐标系.默认情况下,origin位于(0.0, 0.0)(左上角).例如,如果您更改了originfor,view1您可以看到(如果需要,请注释前面的代码),现在左上角view2触摸了view1一个.动机很简单.你说view1,它的左上角是现在的位置(20.0, 20.0),但由于view2的frame origin距离开始(20.0, 20.0),他们将一致.
CGRect frame = view1.bounds;
frame.origin.x += 20.0f;
frame.origin.y += 20.0f;
view1.bounds = frame;
Run Code Online (Sandbox Code Playgroud)
该origin代表view的地位及其内superview,但描述的位置bounds中心.
最后,bounds而origin不是相关的概念.两者都允许导出frame视图(参见前面的等式).
View1的案例研究
以下是使用以下代码段时发生的情况.
UIView* view1 = [[UIView alloc] initWithFrame:CGRectMake(30.0f, 20.0f, 400.0f, 400.0f)];
view1.backgroundColor = [UIColor redColor];
[[self view] addSubview:view1];
NSLog(@"view1's frame is: %@", NSStringFromCGRect([view1 frame]));
NSLog(@"view1's bounds is: %@", NSStringFromCGRect([view1 bounds]));
NSLog(@"view1's center is: %@", NSStringFromCGPoint([view1 center]));
Run Code Online (Sandbox Code Playgroud)
相对的形象.

相反,如果我更改[self view]如下所示的界限会发生什么.
// previous code here...
CGRect rect = [[self view] bounds];
rect.origin.x += 30.0f;
rect.origin.y += 20.0f;
[[self view] setBounds:rect];
Run Code Online (Sandbox Code Playgroud)
相对的形象.

在这里你说它的[self view]左上角现在位于(30.0,20.0)位置,但由于view1帧的起点是从(30.0,20.0)开始,它们将重合.
其他参考(如果需要,可与其他参考资料一起更新)
关于clipsToBounds(来源Apple doc)
将此值设置为YES会导致子视图被剪切到接收器的边界.如果设置为NO,则不会剪切其帧超出接收器可见边界的子视图.默认值为NO.
换句话说,如果视图frame是(0, 0, 100, 100)并且其子视图是(90, 90, 30, 30),则您将只看到该子视图的一部分.后者不会超过父视图的范围.
masksToBounds相当于clipsToBounds.而不是a UIView,此属性应用于a CALayer.在引擎盖下,clipsToBounds打电话masksToBounds.如需进一步参考,请查看UIView的clipsToBounds和CALayer的masksToBounds之间的关系如何?.
Sur*_*gch 131
这个问题已经有了一个很好的答案,但我想补充一些更多的图片.我的完整答案就在这里.
为了帮助我记住框架,我想到了墙上的相框.就像图片可以移动到墙上的任何地方一样,视图框架的坐标系是超视图.(wall = superview,frame = view)
为了帮助我记住边界,我想到了篮球场的界限.篮球就在球场内的某个地方,就像视线边界的坐标系在视野内一样.(court = view,basketball/players =视图内容)
与框架一样,view.center也在superview的坐标中.
黄色矩形表示视图的框架.绿色矩形表示视图的边界.两个图像中的红点表示帧的原点或坐标系内的边界.
Frame
origin = (0, 0)
width = 80
height = 130
Bounds
origin = (0, 0)
width = 80
height = 130
Run Code Online (Sandbox Code Playgroud)

Frame
origin = (40, 60) // That is, x=40 and y=60
width = 80
height = 130
Bounds
origin = (0, 0)
width = 80
height = 130
Run Code Online (Sandbox Code Playgroud)

Frame
origin = (20, 52) // These are just rough estimates.
width = 118
height = 187
Bounds
origin = (0, 0)
width = 80
height = 130
Run Code Online (Sandbox Code Playgroud)

这与示例2相同,除了这次显示视图的整个内容,如果它没有被剪切到视图的边界,它将看起来像.
Frame
origin = (40, 60)
width = 80
height = 130
Bounds
origin = (0, 0)
width = 80
height = 130
Run Code Online (Sandbox Code Playgroud)

Frame
origin = (40, 60)
width = 80
height = 130
Bounds
origin = (280, 70)
width = 80
height = 130
Run Code Online (Sandbox Code Playgroud)

再次,请参阅此处获取更多详细信息的答案.
Erb*_* Mo 88
我发现这个图像对于理解框架,边界等最有帮助.

另请注意frame.size != bounds.size图像旋转时.
我想如果你从这个角度去思考的话CALayer,一切就更清楚了。
框架实际上根本不是视图或图层的独特属性,它是一个虚拟属性,根据边界、位置(UIView中心)和变换计算。
因此,基本上,图层/视图布局实际上是由这三个属性(和anchorPoint)决定的,并且这三个属性中的任何一个都不会更改任何其他属性,例如更改变换不会更改边界。
| 归档时间: |
|
| 查看次数: |
210845 次 |
| 最近记录: |