【iOS】frame与bounds区别

文章目录

  • 前言
  • frame
  • bounds
  • 两者区别
  • size的区别
  • 总结

前言

在学习响应者链的过程中用到了frame与bounds的混用,这两个属性经常出现在我们的开发中,特别撰写一篇博客分析区别

首先,我们来看一下iOS特有的坐标系,在iOS坐标系中以左上角为坐标原点,往右为X正方向,往下是Y正方向如下图:

我们来看一下frame与bounds在文件中的定义

bounds

默认边界为原点0,frame大小。可以做成动画

frame

可以做成动画。如果视图被转换,不要使用frame,因为它不能正确反映视图的实际位置。使用bounds + center代替

同时可以看到他们都是CGRect结构体

bash 复制代码
struct CGRect {
    CGPoint origin;
    CGSize size;
};

origin决定了view的起点,size决定View的尺寸

frame

frame描述的是视图相对于它的父视图 的坐标系统中的位置和大小。它包含一个CGRect值,定义视图的原点位置和宽高。

  • 坐标系:父视图的坐标系。
  • 内容:包含视图的原点相对于父视图的位置,以及视图的宽度和高度。
  • 应用:适合在父视图中设置视图的位置和大小

来看一段Demo

bash 复制代码
UIView *viewA = [[UIView alloc] initWithFrame:CGRectMake(50, 50, 300, 300)];
[viewA setBackgroundColor:[UIColor blueColor]];
[self.view addSubview:viewA];
NSLog(@"viewA - %@",NSStringFromCGRect(viewA.frame));

UIView *viewB = [[UIView alloc] initWithFrame:CGRectMake(50, 50, 200, 200)];
[viewB setBackgroundColor:[UIColor yellowColor]];
[viewA addSubview:viewB];
NSLog(@"viewB - %@",NSStringFromCGRect(viewB.frame));

UIView *viewC = [[UIView alloc] initWithFrame:CGRectMake(100, 100, 100, 100)];
[viewC setBackgroundColor:[UIColor redColor]];
[self.view addSubview:viewC];
NSLog(@"viewC - %@",NSStringFromCGRect(viewC.frame));

输出:

以上可以看出,viewB和viewC的起点重合

但是从打印结果来看,viewB的起点为(50,50),而viewC的起点为(100,100)

原因就是frame中的位置是以父视图的坐标系为标准来确定当前视图的位置

viewB的父视图为viewA,viewC的父视图为self.view,而由于viewA的起点为(50,50),所以viewB与viewC起点才会重合。

bounds

我们再打印一下bounds

bash 复制代码
    UIView *viewA = [[UIView alloc] initWithFrame:CGRectMake(50, 50, 300, 300)];
    [viewA setBackgroundColor:[UIColor blueColor]];
    [self.view addSubview:viewA];
    NSLog(@"viewA - %@",NSStringFromCGRect(viewA.bounds));
    
    UIView *viewB = [[UIView alloc] initWithFrame:CGRectMake(50, 50, 200, 200)];
    [viewB setBackgroundColor:[UIColor yellowColor]];
    [viewA addSubview:viewB];
    NSLog(@"viewB - %@",NSStringFromCGRect(viewB.bounds));
    
    UIView *viewC = [[UIView alloc] initWithFrame:CGRectMake(100, 100, 100, 100)];
    [viewC setBackgroundColor:[UIColor redColor]];
    [self.view addSubview:viewC];
    NSLog(@"viewC - %@",NSStringFromCGRect(viewC.bounds));

可以看到bounds的起点都是0

这也符合文档中的说明默认边界为原点0,frame大小。可以做成动画

每个视图都有自己的坐标系,且这个坐标系默认以自身的左上角为坐标原点 ,所有子视图以这个坐标系的原点为基准点。
bounds的位置代表的是子视图看待当前视图左上角的位置,bounds的大小代表当前视图的大小。

  • 修改frame会改变视图在父视图中的位置。
  • 修改bounds不会改变视图在父视图中的位置,只会改变其内部内容的绘制区域,也就是会改变子视图的位置、

两者区别

此时,如果我们把ViewAbounds改为(0,100),结果如下:

此时父视图左上角不再是(0,0),而是(0,50),因此子视图才会往上移动

size的区别

frame的size直接决定了view的大小,而bounds的size修改后,view的中心点不变,长宽以中心点进行缩放

看Demo:

bash 复制代码
    UIView *viewA = [[UIView alloc] initWithFrame:CGRectMake(50, 50, 300, 300)];
    [viewA setBackgroundColor:[UIColor blueColor]];
    viewA.bounds = CGRectMake(50, 50, 300, 300);
    [self.view addSubview:viewA];
    NSLog(@"viewA - %@",NSStringFromCGRect(viewA.bounds));


修改bounds为CGRectMake(50, 50, 100, 100)

中心点没变,只是中心点进行了缩放

总结

坐标系不同
frame:父视图坐标系,用于确定视图在父视图中的位置。
bounds:自身坐标系,用于描述视图内容区域的布局。
位置与布局
frame用于确定视图在父视图中的整体位置和大小。
bounds修改origal自身不变化,会影响子视图,修改size以自身中心点进行缩放

参考博客:frame与bounds的区别详解

相关推荐
与火星的孩子对话11 小时前
Unity进阶课程【六】Android、ios、Pad 终端设备打包局域网IP调试、USB调试、性能检测、控制台打印日志等、C#
android·unity·ios·c#·ip
九丝城主21 小时前
2025使用VM虚拟机安装配置Macos苹果系统下Flutter开发环境保姆级教程--上篇
服务器·flutter·macos·vmware
芳草萋萋鹦鹉洲哦1 天前
【vue3+tauri+rust】如何实现下载文件mac+windows
windows·macos·rust
恋猫de小郭1 天前
Flutter Widget Preview 功能已合并到 master,提前在体验毛坯的预览支持
android·flutter·ios
点金石游戏出海2 天前
每周资讯 | Krafton斥资750亿日元收购日本动画公司ADK;《崩坏:星穹铁道》新版本首日登顶iOS畅销榜
游戏·ios·业界资讯·apple·崩坏星穹铁道
旷世奇才李先生2 天前
Swift 安装使用教程
开发语言·ios·swift
90后的晨仔2 天前
Xcode16报错: SDK does not contain 'libarclite' at the path '/Applicati
ios
finger244802 天前
谈一谈iOS线程管理
ios·objective-c
Digitally2 天前
如何将大型视频文件从 iPhone 传输到 PC
ios·iphone
梅名智2 天前
IOS 蓝牙连接
macos·ios·cocoa