【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的区别详解

相关推荐
叽哥4 小时前
Flutter Riverpod上手指南
android·flutter·ios
用户091 天前
SwiftUI Charts 函数绘图完全指南
ios·swiftui·swift
YungFan1 天前
iOS26适配指南之UIColor
ios·swift
权咚2 天前
阿权的开发经验小集
git·ios·xcode
用户092 天前
TipKit与CloudKit同步完全指南
ios·swift
小溪彼岸2 天前
macOS自带截图命令ScreenCapture
macos
法的空间2 天前
Flutter JsonToDart 支持 JsonSchema
android·flutter·ios
2501_915918412 天前
iOS 上架全流程指南 iOS 应用发布步骤、App Store 上架流程、uni-app 打包上传 ipa 与审核实战经验分享
android·ios·小程序·uni-app·cocoa·iphone·webview
TESmart碲视2 天前
Mac 真正多显示器支持:TESmart USB-C KVM(搭载 DisplayLink 技术)如何实现
macos·计算机外设·电脑
00后程序员张2 天前
iOS App 混淆与加固对比 源码混淆与ipa文件混淆的区别、iOS代码保护与应用安全场景最佳实践
android·安全·ios·小程序·uni-app·iphone·webview