ZJ_iOS面试iOS学习笔记程序员

iOS基础--浅析frame,bounds,和center

2015-11-20  本文已影响1000人  李xiao屁的忧伤

首先我们必须明确一点,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] ;

结果如下:

result1.png

从图中三个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] ;
result2.png

对比两张图片的结果,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] ;

结果如下:


result3.png

对比结果1,我们发现,在window的bounds值改变后,三张视图发生了整体移动.
一般如果我们不指定bounds值,系统默认左上角的bounds值就是(0,0),而当我们指定为(50,100)后,意味着左上角的位置已经不再是(0,0),而是我们制定的(50,100) .在它上边的所有子类在根据frame找位置的时候依然是从(0,0)开始的,只不过(0,0)已经不是左上角我们能看见的位置了,而是跑出了屏幕.如下图:

result 4.png

屏幕左上角为(50,100) ,(0,0)已经出了屏幕
从图上我们可以直观的得到结论:
frame改变的是自身在父View上的位置,而bounds改变的是子类在该View上的位置.
在最后我们用三张简单的图片来概括frame,bounds和center的关系.

frame和bounds的关系.png frame和center的关系.png bounds和center的关系.png
上一篇下一篇

猜你喜欢

热点阅读