我想知道如何以正确的方式使用这些属性。

据我所知,frame可以从我正在创建的视图的容器中使用。 它设置了相对于容器视图的视图位置。它还设置了视图的大小。

也可以从我正在创建的视图容器中使用center。此属性更改视图相对于其容器的位置。

最后,bounds是相对于视图本身的。它改变了视图的可绘制区域。

你能提供更多关于框架和边界关系的信息吗?clipsToBounds和masksToBounds属性如何?


当前回答

我认为如果你从CALayer的角度来思考,一切都更清楚了。

Frame并不是视图或层的独立属性,它是一个虚拟属性,由边界、位置(UIView的中心)和变换计算而来。

所以基本上图层/视图布局是由这三个属性(和anchorPoint)决定的,这三个属性中的任何一个都不会改变任何其他属性,比如改变transform不会改变边界。

其他回答

我发现这张图对理解框架、边界等很有帮助。

也请注意这个框架。Size != bounds。图像旋转时的大小。

这个问题已经有了一个很好的答案,但是我想补充一些图片。我的完整答案在这里。

为了帮助我记住框架,我想到了墙上的相框。就像图片可以在墙上的任何地方移动一样,视图框架的坐标系统是父视图。(墙=父视图框架=视图)

为了帮助我记住边界,我想到了篮球场的边界。篮球在球场内的某个地方就像视图边界的坐标系在视图本身内一样。(球场=视图,篮球/球员=视图内的内容)

像框,视图。Center也在父视图的坐标中。

框架与边界-示例1

黄色矩形表示视图的框架。绿色矩形表示视图的边界。两个图像中的红点都表示坐标系中的原点或边界。

Frame
    origin = (0, 0)
    width = 80
    height = 130

Bounds 
    origin = (0, 0)
    width = 80
    height = 130


示例2

Frame
    origin = (40, 60)  // That is, x=40 and y=60
    width = 80
    height = 130

Bounds 
    origin = (0, 0)
    width = 80
    height = 130


示例3

Frame
    origin = (20, 52)  // These are just rough estimates.
    width = 118
    height = 187

Bounds 
    origin = (0, 0)
    width = 80
    height = 130


示例4

这与示例2相同,只是这次显示的是视图的整个内容,就像它没有被剪切到视图的边界一样。

Frame
    origin = (40, 60)
    width = 80
    height = 130

Bounds 
    origin = (0, 0)
    width = 80
    height = 130


示例5

Frame
    origin = (40, 60)
    width = 80
    height = 130

Bounds 
    origin = (280, 70)
    width = 80
    height = 130

再一次,看这里我的答案和更多的细节。

这篇文章有非常好的答案和详细的解释。我只是想说,在WWDC 2011的视频《理解UIKit渲染》中,从@4:22到20:10,有另一个关于帧、边界、中心、变换、边界原点的视觉表示的解释

看完以上答案,在此加上我的解读。

假设在线浏览,网页浏览器是你的框架,它决定在哪里和多大显示网页。浏览器的滚动条是你的边界。来源,决定网页的哪一部分将被显示。范围之内。起源很难理解。最好的学习方法是创建单视图应用程序,尝试修改这些参数并查看子视图如何变化。

- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.

UIView *view1 = [[UIView alloc] initWithFrame:CGRectMake(100.0f, 200.0f, 200.0f, 400.0f)];
[view1 setBackgroundColor:[UIColor redColor]];

UIView *view2 = [[UIView alloc] initWithFrame:CGRectInset(view1.bounds, 20.0f, 20.0f)];
[view2 setBackgroundColor:[UIColor yellowColor]];
[view1 addSubview:view2];

[[self view] addSubview:view1];

NSLog(@"Old view1 frame %@, bounds %@, center %@", NSStringFromCGRect(view1.frame), NSStringFromCGRect(view1.bounds), NSStringFromCGPoint(view1.center));
NSLog(@"Old view2 frame %@, bounds %@, center %@", NSStringFromCGRect(view2.frame), NSStringFromCGRect(view2.bounds), NSStringFromCGPoint(view2.center));

// Modify this part.
CGRect bounds = view1.bounds;
bounds.origin.x += 10.0f;
bounds.origin.y += 10.0f;

// incase you need width, height
//bounds.size.height += 20.0f;
//bounds.size.width += 20.0f;

view1.bounds = bounds;

NSLog(@"New view1 frame %@, bounds %@, center %@", NSStringFromCGRect(view1.frame), NSStringFromCGRect(view1.bounds), NSStringFromCGPoint(view1.center));
NSLog(@"New view2 frame %@, bounds %@, center %@", NSStringFromCGRect(view2.frame), NSStringFromCGRect(view2.bounds), NSStringFromCGPoint(view2.center));

我认为如果你从CALayer的角度来思考,一切都更清楚了。

Frame并不是视图或层的独立属性,它是一个虚拟属性,由边界、位置(UIView的中心)和变换计算而来。

所以基本上图层/视图布局是由这三个属性(和anchorPoint)决定的,这三个属性中的任何一个都不会改变任何其他属性,比如改变transform不会改变边界。