美文网首页
frame和bounds实验1 2022-03-14 周一

frame和bounds实验1 2022-03-14 周一

作者: 松哥888 | 来源:发表于2022-03-17 10:34 被阅读0次

简介

frame是父视图坐标系中的位置和大小;bounds是自身视图坐标系中的位置和大小。

其中,不管是frame还是bounds,大小这点一样,代表矩形的长和宽,这个很好理解。可是,原点位置呢?frame很好理解。但是bounds呢?什么叫做自身坐标系?真的是太难理解了。

frame和bounds的区别
这篇文章中的有一句话说的很对:

它是参考自己坐标系,它可以修改自己坐标系的原点位置,进而影响到“子view”的显示位置。

实验场景

默认的self.view设置为蓝色;父view设置为红色;子view设置为黄色。代码如下:

#import "ViewController.h"

@interface ViewController ()

@property (nonatomic, strong) UIView *fatherView;
@property (nonatomic, strong) UIView *sonView;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    
    self.fatherView = [[UIView alloc] init];
    self.sonView = [[UIView alloc] init];
    
    [self.fatherView addSubview:self.sonView];
    [self.view addSubview:self.fatherView];
    
    // 父视图
    self.fatherView.backgroundColor = [UIColor redColor];
    // 子视图
    self.sonView.backgroundColor = [UIColor yellowColor];
    
    // 背景视图
    self.view.backgroundColor = [UIColor blueColor];
}

- (void)viewWillLayoutSubviews {
    self.fatherView.frame = CGRectMake(100, 100, 200, 200);
    self.sonView.bounds = CGRectMake(0, 0, 100, 100);
    
    NSLog(@"fatherView frame:%@ ====== fatherView bounds:%@", NSStringFromCGRect(self.fatherView.frame), NSStringFromCGRect(self.fatherView.bounds));
    NSLog(@"sonView frame:%@ ====== sonView bounds:%@", NSStringFromCGRect(self.sonView.frame), NSStringFromCGRect(self.sonView.bounds));
}

@end

在这里,位置的设置就两句话:

self.fatherView.frame = CGRectMake(100, 100, 200, 200);
self.sonView.bounds = CGRectMake(0, 0, 100, 100);

父view设置了frame,子view设置了bounds。实际效果如下:

效果图

打印信息如下:

fatherView frame:{{100, 100}, {200, 200}} ====== fatherView bounds:{{0, 0}, {200, 200}}
sonView frame:{{-50, -50}, {100, 100}} ====== sonView bounds:{{0, 0}, {100, 100}}

通过打印信息和图片位置的对比,父view可以理解;子view的大小也没问题,可是子view的原点(-50,-50)是怎么来的?

改动1:修改子view的bounds原点

比如self.sonView.bounds = CGRectMake(50, 50, 100, 100);
或者self.sonView.bounds = CGRectMake(20, 30, 100, 100);
... ...
不论怎么改,只要不改大小,父子视图位置关系始终不变。

这说明bounds的原点不会影响自己的位置;

改动2:修改子view的bounds大小

既然子view的bounds的原点不影响自己在父view中的位置,那么就保持(0,0)不变,那么就修改bounds的大小试试。
做了几次实验,结果如下:

self.sonView.bounds = CGRectMake(0, 0, 50, 50);
// sonView frame:{{-25, -25}, {50, 50}}
self.sonView.bounds = CGRectMake(0, 0, 100, 100);
// sonView frame:{{-50, -50}, {100, 100}}
self.sonView.bounds = CGRectMake(0, 0, 200, 200);
// sonView frame:{{-100, -100}, {200, 200}}

总感觉原点的位置是长宽的一半,然后加个负号;比如w=100时,x=-50
是巧合吗?h=100时,y= -50

子view加上frame

考虑到子view没有加frame,只是加了bounds。那么猜想,子view默认的frame应该是全0,也就是self.sonView.frame = CGRectMake(0, 0, 0, 0);
那么,加上bounds之后,子view的frame的原点该怎么确定呢?

  • 公式猜想:
self.sonView.frame = CGRectMake(fx, fy, fw, fh);
self.sonView.bounds = CGRectMake(bx, by, bw, bh);

经过以上两个语句之后,大小是bw和bh,这个会覆盖,没有疑问,也很好理解。但是x和y呢? 有如下公式:

x = fx + (fw - bw)/ 2;
y = fy + (fh - bh)/ 2;

简单讲就是如果bounds的大小变了,就是偏移大小变化的一半。
比如:-50 = 0 + (0 - 100)/ 2

  • 又实验了几组数据,结果如下:
    self.sonView.frame = CGRectMake(0, 0, 80, 50);
    self.sonView.bounds = CGRectMake(0, 0, 100, 100);
// sonView frame:{{-10, -25}, {100, 100}} 
// x: -10 = 0 + (80 - 100) / 2
// y: -25 = 0 + (50 - 100) / 2
    self.sonView.frame = CGRectMake(0, 30, 80, 150);
    self.sonView.bounds = CGRectMake(0, 0, 100, 100);
// sonView frame:{{-10, 55}, {100, 100}} 
// x: -10 = 0 + (80 - 100) / 2
// y: 55 = 30 + (150 - 100) / 2
    self.sonView.frame = CGRectMake(-10, 30, 180, 150);
    self.sonView.bounds = CGRectMake(0, 0, 100, 100);
// sonView frame:{{30, 55}, {100, 100}} 
// x: 30 = -10 + (180 - 100) / 2
// y: 55 = 30 + (150 - 100) / 2

实验了几组数据,基本吻合。

修改父view的bounds

  • 大小只改变父view自己,对于子view没有影响。

  • 原点不会改变子view的frame,但是会改变子view的位置。

  • 父view不改bounds,情况很正常

    self.fatherView.frame = CGRectMake(100, 100, 200, 200);
    self.sonView.frame = CGRectMake(0, 0, 100, 100);
    // sonView frame:{{0, 0}, {100, 100}}
正常图片
  • 父view修改bounds的原点,子view偏了
    self.fatherView.frame = CGRectMake(100, 100, 200, 200);
    self.fatherView.bounds = CGRectMake(20, 40, 200, 200);
    self.sonView.frame = CGRectMake(0, 0, 100, 100);
    // sonView frame:{{0, 0}, {100, 100}}
子view偏了

原来被认为是(0,0)的地方,现在变成了(20,40)。所以(0,0)跑左上角去了。

相关文章

网友评论

      本文标题:frame和bounds实验1 2022-03-14 周一

      本文链接:https://www.haomeiwen.com/subject/gwmsdrtx.html