iOS——frame & bounds

前言

在iOS中我们经常会对控件位置调整,利用到了bounds和frame,但是一直没搞懂他俩的区别,今天记录一下。

frame和bounds简介

在这里插入图片描述

  • frame: 该view在父view坐标系统中的位置和大小。(参照点是,父亲的坐标系统)
  • bounds:该view在本地坐标系统中的位置和大小。(参照点是,本地坐标系统,就相当于ViewB自己的坐标系统,以0,0点为起点)。

下面通过一段简单的代码对比一下。

//
//  ViewController.m
//  frameAndbounds
//
//  Created by 差不多先生 on 2022/10/3.
//

#import "ViewController.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    UIView* view1 = [[UIView alloc] initWithFrame:CGRectMake(100, 100, 200, 200)];
    view1.backgroundColor = [UIColor redColor];
    [self.view addSubview:view1];
    NSLog(@"view1 frame:%@========view1 bounds:%@",NSStringFromCGRect(view1.frame),NSStringFromCGRect(view1.bounds));
        
    UIView* view2 = [[UIView alloc] initWithFrame:CGRectMake(10, 10, 100, 100)];
    view2.backgroundColor = [UIColor yellowColor];
    [view1 addSubview:view2];
    NSLog(@"view2 frame:%@========view2 bounds:%@",NSStringFromCGRect(view2.frame),NSStringFromCGRect(view2.bounds));

}


@end

看看效果:
在这里插入图片描述
在这里插入图片描述

我们往根视图添加了view1,再在view1上添加了view2.

根据对比frame和bounds的数值,很容易理解,frame对应的原点是根据父视图决定的,而bounds的原点是根据自身决定的,也就是本地。

下面我们修改view1的bounds。

    [view1 setBounds:CGRectMake(-20, -20, 200, 200)];

在这里插入图片描述
我们对view1修改bounds却让view2移动了。
这是因为setBounds的作用是:强制将自己(view1)本地坐标系的原点改为(-20,-20)。这个(-20,-20)是相对view1的父view(self.view)偏移的。也就是向左上角偏移。
那么在view1的坐标系中(0,0)这个点是需要向右下各偏移20。

因为view1的subview(view2)的frame参照的坐标系是父view(view1)的bounds设置的,而此时view2的frame设置为(0,0),就会导致view2向右下各偏移20。如上图所示。

所以,bounds的有这么一个特点:
它是参考自己坐标系,它可以修改自己坐标系的原点位置,进而影响到“子view”的显示位置。

bounds的应用

其实bounds我们一直在使用,就是我们使用scrollview的时候。
我们设置了一个整页屏幕,但是在滑动时,可以显示图片之外的东西,就是因为scrollview在不断改变自己的bounds,从而改变scrollview上的子view的frame,让他们的frame始终在最顶级view(window)的frame内部,这样我们就可以始终看到内容了。
在滚动时image和scrollview的frame都没变,唯一在不断改变的是scrollview的contentoffset和bounds,而且两者完全相同。

bouns大于frame的情况

//
//  ViewController.m
//  frameAndbounds
//
//  Created by 差不多先生 on 2022/10/3.
//

#import "ViewController.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    UIView* view1 = [[UIView alloc] initWithFrame:CGRectMake(100, 100, 200, 200)];
    view1.backgroundColor = [UIColor redColor];
    [self.view addSubview:view1];
    NSLog(@"view1 frame:%@========view1 bounds:%@",NSStringFromCGRect(view1.frame),NSStringFromCGRect(view1.bounds));
    
    [view1 setBounds:CGRectMake(-20, -20, 400, 400)];
    NSLog(@"view1 frame:%@========view1 bounds:%@",NSStringFromCGRect(view1.frame),NSStringFromCGRect(view1.bounds));
    UIView* view2 = [[UIView alloc] initWithFrame:CGRectMake(10, 10, 100, 100)];
    view2.backgroundColor = [UIColor yellowColor];
    [view1 addSubview:view2];
    NSLog(@"view2 frame:%@========view2 bounds:%@",NSStringFromCGRect(view2.frame),NSStringFromCGRect(view2.bounds));

}


@end

假设设置了控件的bounds大于frame,那么此时会导致frame被撑大,frame的x,y,width,height都会改变。

  • 新的frame的size等于bound的size。
  • 新的frame.x = 旧frame.x - (bounds.size.witdh - 旧frame.size.width)/2
  • 新的frame.y = 旧frame.y - (bounds.size.height - 旧frame.size.height)/2
    在这里插入图片描述
    在这里插入图片描述
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值