美文网首页
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