美文网首页
Frame和bounds的区别

Frame和bounds的区别

作者: KB_MORE | 来源:发表于2020-08-06 14:15 被阅读0次

在iOS中我们会经常遇到frame和bounds,这两个概念很相似,但是也有区别。frame还好理解,但是bounds就比较容易迷惑人。我们通过实例来讲解下bounds的概念,然后再看看bounds有哪些用途,这样就可以彻底搞清楚bounds了。

frame和bounds简介

先看一张图:

image
  • frame: 该view在父view坐标系统中的位置和大小。(参照点是,父亲的坐标系统)
  • bounds:该view在本地坐标系统中的位置和大小。(参照点是,本地坐标系统,就相当于ViewB自己的坐标系统,以0,0点为起点)。

其实本地坐标系统的关键就是要知道的它的原点(0,0)在父坐标系统中的什么位置(这个位置是相对于父view的本地坐标系统而言的,最终的父view就是UIWindow,它的本地坐标系统原点就是屏幕的左上角了)。

通过修改viewbounds属性可以修改本地坐标系统的原点位置。
图中viewA为父视图, viewB为子视图,如果要调整viewB在viewA上的位置则有两种方式

  • 通过调整ViewB的frame, 这个比较容易想到
  • 通过ViewA的bounds来调整

frame我相信大家都理解的比较清楚,但是bounds光是这么说估计大家都很迷糊,那么我们下面来看具体的实例。

bounds到底起什么作用

示例代码:

    UIView *view1 = [[UIView alloc] initWithFrame:CGRectMake(100, 100, 200, 200)];
    view1.backgroundColor = [UIColor redColor];
    [self.view addSubview:view1];//添加到self.view
    NSLog(@"view1 frame:%@========view1 bounds:%@",NSStringFromCGRect(view1.frame),NSStringFromCGRect(view1.bounds));
    
    UIView *view2 = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];
    view2.backgroundColor = [UIColor yellowColor];
    [view1 addSubview:view2];//添加到view1上,[此时view1坐标系左上角起点为(-20,-20)]
    NSLog(@"view2 frame:%@========view2 bounds:%@",NSStringFromCGRect(view2.frame),NSStringFromCGRect(view2.bounds));

效果图:

图片.png

输出日志:

view1 frame:{{100, 100}, {200, 200}}========view1 bounds:{{0, 0}, {200, 200}}

view2 frame:{{0, 0}, {100, 100}}========view2 bounds:{{0, 0}, {100, 100}}

这个是常规的场景,我相信大家都能理解。

下面我们来改变view1的bounds,代码如下

    [view1 setBounds:CGRectMake(-20, -20, 200, 200)];

此时显示和输出日志如下所示:


图片.png
 view1 frame:{{100, 100}, {200, 200}}========view1 bounds:{{-20, -20}, {200, 200}}

view2 frame:{{0, 0}, {100, 100}}========view2 bounds:{{0, 0}, {100, 100}}

分析

上面设置view1的bounds的代码起到了让view2的位置改变的作用。为何(-20,-20)的偏移量,却可以让view2向右下角移动呢?

这是因为setBounds的作用是:强制将自己(view1)本地坐标系的原点改为(-20,-20)。这个(-20,-20)是相对view1的父view(self.view)偏移的。也就是向左上角偏移。

那么在view1的坐标系中(0,0)这个点是需要向右下各偏移20。

因为view1的subview(view2)的frame参照的坐标系是父view(view1)的bounds设置的,而此时view2的frame设置为(0,0),就会导致view2向右下各偏移20。如上图所示。

总结

所以,bounds的有这么一个特点:
它是参考自己坐标系,它可以修改自己坐标系的原点位置,进而影响到“子view”的显示位置。

bounds使用场景

其实bounds我们一直在使用,就是我们使用scrollview的时候。
为什么我们滚动scrollview可以看到超出显示屏的内容。就是因为scrollview在不断改变自己的bounds,从而改变scrollview上的子view的frame,让他们的frame始终在最顶级view(window)的frame内部,这样我们就可以始终看到内容了。

下面通过一个具体的例子来看看:


    self.imageview = [[UIImageView alloc]initWithFrame:CGRectMake(100,0, 50, 1000)];
    self.imageview.image = [UIImage imageNamed:@"1"];
    self.imageview.contentMode = UIViewContentModeScaleAspectFill;
    self.scrollview.contentSize = self.imageview.frame.size;
    [self.scrollview addSubview:self.imageview];
    

在向上滚动过程中,输出scrollview的frame,bouns,contentoffset和子控件imageview的frame,bounds

-(void)scrollViewDidScroll:(UIScrollView *)scrollView{
    NSLog(@"scrollview[contentoffset:%@---frame:%@------bounds:%@",NSStringFromCGPoint(scrollView.contentOffset), NSStringFromCGRect(self.scrollview.frame),NSStringFromCGRect(self.scrollview.bounds));
    NSLog(@"imageview[frame:%@------bounds:%@",NSStringFromCGRect(self.imageview.frame),NSStringFromCGRect(self.imageview.bounds));
}

输出结果如下:


图片.png

分析:

可以看到imageview的frame和bounds还有scrollview的frame是没有改变的。唯一在不断改变的是scrollview的contentoffset和bounds,而且两者完全相同。

结合上面我们讲的知识,就不难理解为什么scrollview要这么做了。

向上滚动scrollview,我们就不断增加scrollview的bounds的y值,也就是不断把scrollview的本地坐标系原点向下偏移(相对于scrollview的父view的坐标系,y值越大,越向下偏移)。那么此时scrollview的子控件的frame设置的(0,0)就是不断向上偏移

假设某一时刻scrollview的坐标系原点为(0,100),那么scrollview的(0,0)位置就是相对于坐标系原点向上偏移100的距离,设置scrollview的子控件的frame为(0,0),就是设置子控件左上角在scrollview中的(0,0)位置,那么子控件就会向上偏移100,你也就看到scrollview的内容(子控件)向上滚动的效果。

其实我们可以使用文章开始的例子来模式UIScrollview的滚动效果,经过上面的分析我们知道就是通过不断增加UIScrollview的bounds的Y值,才可以出现滚动效果从而显示超出屏幕的内容。

那么使用文章开头的例子,我们可以不断增加view1的bounds的y值,来看看是不是可以达到同样的效果:view1不动,view2在不断向上滚动

代码如下:

    UIView *view1 = [[UIView alloc] initWithFrame:CGRectMake(100, 200, 200, 100)];
    view1.backgroundColor = [UIColor redColor];
    [self.view addSubview:view1];//添加到self.view
   
    
    UIView *view2 = [[UIView alloc] initWithFrame:CGRectMake(20, 0, 100, 1000)];
    view2.backgroundColor = [UIColor yellowColor];
    [view1 addSubview:view2];//添加到view1上,[此时view1坐标系左上角起点为(-20,-20)]
    
    [UIView animateWithDuration:3.0 animations:^{
        [view1 setBounds:CGRectMake(0, 1000, 200, 100)];
    }];

运行看看,可以发现view1固定不动,view2在不断向上滚动,此时的view1就相当于UIScrollview,而view2相当于UIScrollview上面显示的内容,现在明白了吗?

bouns大于frame的情况

假设设置了控件的bounds大于frame,那么此时会导致frame被撑大,frame的x,y,width,height都会改变。

图片.png

结论

    新的frame的size等于bound的size。
    新的frame.x = 旧frame.x - (bounds.size.witdh - 旧frame.size.width)/2
    新的frame.y = 旧frame.y - (bounds.size.height - 旧frame.size.height)/2

bound的改变会累加

假设view1上面添加了view2,view2上面添加了view3。三个view的size都是(100,100)。
我们设置如下:

view1.bound = (0,100,100,100)

view2.bound = (0,100,100,100)

那么此时view3.frame = (0,0,100,100),view3会相对于原来没有设置view1、view2的bound时的位置向上偏移200。
总结

frame是参考父view的坐标系来设置自己左上角的位置。
设置bounds可以修改自己坐标系的原点位置,进而影响到其“子view”的显示位置。

转载https://www.jianshu.com/p/964313cfbdaa

相关文章

  • iOS纪录

    (1)View的Frame与Bounds区别 摘自 ios view的frame和bounds之区别(位置和大小)...

  • 深入探究frame和bounds的区别以及setbounds使用

    深入探究frame和bounds的区别以及setbounds使用 深入探究frame和bounds的区别以及set...

  • iOS 面试题目

    1、iOS frame和Bounds 以及frame和bounds区别2、 ios webView 加载HTML字...

  • #1 布局相关的问题集合

    1.frame 和 bounds的区别 what's the difference bewteen frame a...

  • UI基础相关

    UI基础相关: Frame 和 bounds的区别:Frame是参照父控件的 bounds是参照自己的 默认是(0...

  • frame和bounds区别

    1、frame不管对于位置还是大小,改变的都是自己本身 2、frame的位置是以父视图的坐标系为参照,从而确定当前...

  • iOS~ frame 和 bounds 的区别和联系

    推荐文章Understanding UIScrollView 1、 frame 和 bounds 的区别和联系 f...

  • bounds和frame的区别

    此情况下,在view.bounds = CGRectMake(x, y, W, H)中,无论x、y怎么设置最后打印...

  • frame 和 bounds 的区别

    frame frame是每个view必备的属性,代表的是当前视图的位置和大小,没有设置他,当前视图是看不到的。 b...

  • frame和bounds的区别

    frame: 该view在父view坐标系统中的位置和大小。(参照点是,父亲的坐标系统) bounds:该view...

网友评论

      本文标题:Frame和bounds的区别

      本文链接:https://www.haomeiwen.com/subject/pxlzrktx.html