iOS--frame和bounds

坐标系

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

bounds和frame都是属于CGRect类型的结构体,系统的定义如下,包含一个CGPoint(起点)和一个CGSize(尺寸)子结构体。

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

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

frame

frame是每个view必备的属性,表示view在父view坐标系统中的位置和大小,参照点是父视图的坐标系统。

示例代码:

objectivec 复制代码
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

objectivec 复制代码
    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也是每个view都有的属性,这个属性我们一般不进行设置,表示view在本地坐标系统中的位置和大小。参照点是本地坐标系统。如果我们对上例打印bounds,将会得到以下结果:

因为我们并没有设置bounds值,那么,bounds到底有什么作用呢。这里强调,每个视图都有自己的坐标系,且这个坐标系默认以自身的左上角为坐标原点,所有子视图以这个坐标系的原点为基准点。bounds的位置代表的是子视图看待当前视图左上角的位置,bounds的大小代表当前视图的大小。原则如下:

  • 更改bounds中的位置对于当前视图没有影响,相当于更改了当前视图的坐标系,对于子视图来说当前视图的左上角已经不再是(0,0), 而是改变后的坐标,坐标系改了,那么所有子视图的位置也会跟着改变。
  • 更改bounds的大小,bounds的大小代表当前视图的长和宽,修改长宽后,中心点继续保持不变, 长宽进行改变,通过bounds修改长宽看起来就像是以中心点为基准点对长宽两边同时进行缩放

两者的区别

origin的区别

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

我们始终要清楚,bounds的位置代表的是子视图看待当前视图左上角的位置。 bounds遵守的原则一中,更改bounds中的位置对于当前视图(ViewA)没有影响,相当于更改了ViewA的坐标系,但是子视图(ViewB)不同,对于ViewB来说ViewA的左上角已经不再是(0,0), 而是(0,100),所以对于ViewB来说,ViewA坐标系的原点其实是在红色箭头所指处的上方100处,而此时ViewB的frame.origin为(200,100),所以ViewB的上边与ViewA上边重合。

如果我们更改ViewA的bounds为(200,0),同理(可以自己思考试试),结果如下

size的区别

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

objectivec 复制代码
    UIView *viewA = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 240)];
    [viewA setBackgroundColor:[UIColor grayColor]];
    [self.view addSubview:viewA];

    UIView *viewB = [[UIView alloc] initWithFrame:CGRectMake(100, 50, 160, 120)];
    [viewB setBackgroundColor:[UIColor blueColor]];
    [viewA addSubview:viewB];

    //viewB设置size(320,160)
    [viewB setBounds:CGRectMake(0, 0, 320, 240)];

设置了size之后的结果,viewB左上点距离viewA显然不为(100,50),而是进行了基于viewB视图中心点的缩放操作

总结

  • frame不管对于位置还是大小,改变的都是自己本身。
  • frame的位置是以父视图的坐标系为参照,从而确定当前视图在父视图中的位置。
  • frame的大小改变时,当前视图的左上角位置不会发生改变,只是大小发生改变。
  • bounds改变位置时,改变的是子视图的位置,自身没有影响;其实就是改变了本身的坐标系原点,默认本身坐标系的原点是左上角。
  • bounds的大小改变时,当前视图的中心点不会发生改变,当前视图的大小发生改变,看起来效果就像缩放一样。
相关推荐
也非非也9 分钟前
iPhone 中国区 AI 落地:Apple 与阿里千问合作的技术观察
大数据·人工智能·ios·agent·iphone·智子
茶底世界之下1 小时前
同一片泳池,清透还是奶油胶片?用 Awaking 做两版成片
ios
2501_916008894 小时前
iOS App 图标、启动屏和多语言搭配 方法,上架前使用KXBuild一次做好 App 图标
ide·vscode·ios·objective-c·个人开发·swift·敏捷流程
2501_915918414 小时前
iOS 推送通知怎么实现,从 APNs p8 密钥到 iOS 真机收到第一条推送
vscode·ios·objective-c·个人开发·swift·敏捷流程
周小董1 天前
[1379]mac安装nvm
macos
茶底世界之下1 天前
雨夜街角裁成方图,人物与冷暖光还能共存吗?
ios
youdexiang1 天前
IOS录音APP拍照记录能和音频同步吗
ios·音视频
bossjuemfc1 天前
不记得文件名时,Mac 上的搜索还能怎么做?
macos
2501_915909061 天前
Windows 打开 Xcode 工程,编译调试 Xcode 项目并和 Mac 同事协作
ide·windows·vscode·macos·ios·个人开发·xcode
互联网江湖1 天前
iPhone Duo跌倒,国产折叠屏手机吃饱?
ios·智能手机·iphone