当前位置: 首页 > news >正文

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
    在这里插入图片描述
    在这里插入图片描述

相关文章:

  • 燕山大学编译原理-(实验1 词法分析、实验2 自顶向下的语法分析程序、实验3 基于 LR(0)方法的语法分析、 实验4 语义分析和中间代码生成)
  • 力扣(LeetCode)276. 栅栏涂色(2022.10.03)
  • Ubuntu系统安装
  • 牛客网专项练习30天Pytnon篇第04天
  • 【目标检测算法】IOU、GIOU、DIOU、CIOU与YOLOv5损失函数
  • 为什么梯度方向一定是函数增大的方向
  • Vue学习第36天——PC端和移动端常用的Vue UI组件库
  • ⌈Linux_ 感受系统美学⌋ 剖释Linux操作系统 | 底层级操作增进Linux内功
  • 数据结构之二叉树
  • 数组与数组名到底该如何理解?
  • 计算机网络——随机接入
  • 【NLP开发】Python实现聊天机器人(微软Azure机器人服务)
  • MyBatis框架总结
  • 10.3国庆作业(UART实验)
  • 西瓜书研读——第五章 神经网络:感知机与多层网络
  • -------------------- 第二讲-------- 第一节------在此给出链表的基本操作
  • Fundebug计费标准解释:事件数是如何定义的?
  • github指令
  • Java面向对象及其三大特征
  • Koa2 之文件上传下载
  • springMvc学习笔记(2)
  • 从0到1:PostCSS 插件开发最佳实践
  • 干货 | 以太坊Mist负责人教你建立无服务器应用
  • 如何使用Mybatis第三方插件--PageHelper实现分页操作
  • 深入浏览器事件循环的本质
  • 实习面试笔记
  • 使用parted解决大于2T的磁盘分区
  • 用Visual Studio开发以太坊智能合约
  • Spark2.4.0源码分析之WorldCount 默认shuffling并行度为200(九) ...
  • zabbix3.2监控linux磁盘IO
  • ​低代码平台的核心价值与优势
  • !!【OpenCV学习】计算两幅图像的重叠区域
  • (2009.11版)《网络管理员考试 考前冲刺预测卷及考点解析》复习重点
  • (3)(3.5) 遥测无线电区域条例
  • (4)logging(日志模块)
  • (6)添加vue-cookie
  • (bean配置类的注解开发)学习Spring的第十三天
  • (MonoGame从入门到放弃-1) MonoGame环境搭建
  • (搬运以学习)flask 上下文的实现
  • (博弈 sg入门)kiki's game -- hdu -- 2147
  • (二)构建dubbo分布式平台-平台功能导图
  • (附源码)springboot猪场管理系统 毕业设计 160901
  • (附源码)ssm基于web技术的医务志愿者管理系统 毕业设计 100910
  • (一)C语言之入门:使用Visual Studio Community 2022运行hello world
  • (转)chrome浏览器收藏夹(书签)的导出与导入
  • (轉貼)《OOD启思录》:61条面向对象设计的经验原则 (OO)
  • .bat文件调用java类的main方法
  • .gitignore文件---让git自动忽略指定文件
  • .Net Core与存储过程(一)
  • .net redis定时_一场由fork引发的超时,让我们重新探讨了Redis的抖动问题
  • .NET 的静态构造函数是否线程安全?答案是肯定的!
  • [ C++ ] 继承
  • [ Linux ] git工具的基本使用(仓库的构建,提交)
  • [2023年]-hadoop面试真题(一)
  • [3D基础]理解计算机3D图形学中的坐标系变换