首先我们必须明确一点,frame和bounds都是一个结构体类型.参看如下代码:
struct CGRect // frame和bounds都属于这一类型
{
CGPoint origin; //坐标位置
CGSize size;//形状大小
};
struct CGPoint // 坐标位置中包含x坐标和y坐标
{
CGFloat x;
CGFloat y;
};
struct CGSize// 形状大小指的是矩形的长和宽
{
CGFloat width;
CGFloat height;
};
在了解了frame和bounds的类型之后,我们还必须要明确一个概念,那就是我们的坐标起点是哪个位置,也就是以哪个位置开始向x轴y轴正方向开始延伸.我们拿我们的手机屏幕为例,左上角就是我们的起点坐标(0,0),向右向下依次为x轴y轴的正方向.
我们以UIView为例,假设我们创建三个UIVIew,分别命名为backView,middleView和frontView.(三个UIView颜色分别为红,黄,蓝).backView是middleView的父类,middleView是frontView的父类.
代码如下:
// 创建最底层的UIView
UIView *backView = [[UIView alloc]initWithFrame:CGRectMake(50,100, 250, 250) ] ;
backView.backgroundColor = [UIColor redColor] ;
[self.window addSubview:backView] ;
// 创建中间层的UIView
UIView *middleView = [[UIView alloc] initWithFrame:CGRectMake(50, 50, 150, 150)] ;
middleView.backgroundColor = [UIColor yellowColor] ;
[backView addSubview:middleView] ;
// 创建最底层的UIView
UIView *frontView = [[UIView alloc] initWithFrame:CGRectMake(35, 35, 80, 80)] ;
frontView.backgroundColor = [UIColor blueColor] ;
[middleView addSubview:frontView] ;
结果如下:
从图中三个UIVIew的位置信息我们可以直观的看到,这三个UIView的origin,也就是他们的坐标,是以父View的左上角为(0,0)点起始的,除了backView外,其余两个并不是以主屏幕左上角为(0,0)起始的.这里我们是不是可以理解为frame只影响UIView自身在父类中的位置呢?
假设,我们改变backView的起始位置,再看一看有什么变化.
// 改变backView的起始位置
UIView *backView = [[UIView alloc]initWithFrame:CGRectMake(100,300, 250, 250) ] ;
backView.backgroundColor = [UIColor redColor] ;
[self.window addSubview:backView] ;
对比两张图片的结果,middleView和frontView随着backView的改变而改变了位置,但是在backView本身的位置却没有改变.那是因为middleView的父类依然是backView,它相对于父类的位置不变.
下面我们再来看看bounds的改变对三个UIView有什么影响.
当一个view设置bounds时,会把自己当成一个容器,定义自己的边界大小以及左上角的初始坐标。
当子视图添加到此视图时,会根据bounds指定的原点(0,0)计算frame,而非左上角。我们依然利用上边的例子,只不过把self.window的bounds值做了改变.
self.window.bounds = CGRectMake(50, 100, CGRectGetWidth([[UIScreen mainScreen] bounds]), CGRectGetHeight([[UIScreen mainScreen] bounds])) ;
UIView *backView = [[UIView alloc]initWithFrame:CGRectMake(50,100, 250, 250) ] ;
backView.backgroundColor = [UIColor redColor] ;
[self.window addSubview:backView] ;
UIView *middleView = [[UIView alloc] initWithFrame:CGRectMake(50, 50, 150, 150)] ;
middleView.backgroundColor = [UIColor yellowColor] ;
[backView addSubview:middleView] ;
UIView *frontView = [[UIView alloc] initWithFrame:CGRectMake(35, 35, 80, 80)] ;
frontView.backgroundColor = [UIColor blueColor] ;
[middleView addSubview:frontView] ;
结果如下:
对比结果1,我们发现,在window的bounds值改变后,三张视图发生了整体移动.
一般如果我们不指定bounds值,系统默认左上角的bounds值就是(0,0),而当我们指定为(50,100)后,意味着左上角的位置已经不再是(0,0),而是我们制定的(50,100) .在它上边的所有子类在根据frame找位置的时候依然是从(0,0)开始的,只不过(0,0)已经不是左上角我们能看见的位置了,而是跑出了屏幕.如下图:
屏幕左上角为(50,100) ,(0,0)已经出了屏幕
从图上我们可以直观的得到结论:
frame改变的是自身在父View上的位置,而bounds改变的是子类在该View上的位置.
在最后我们用三张简单的图片来概括frame,bounds和center的关系.