必威-必威-欢迎您

必威,必威官网企业自成立以来,以策略先行,经营致胜,管理为本的商,业推广理念,一步一个脚印发展成为同类企业中经营范围最广,在行业内颇具影响力的企业。

本文主要阐述Frame和bound的区别,也许是我们敲的

2019-09-12 19:42 来源:未知
2016-08-23 10:52:30.926 frame和bounds区别[1038:38905] log1:{{50, 100}, {200, 200}}2016-08-23 10:52:30.927 frame和bounds区别[1038:38905] log2:{{0, 50}, {300, 300}}

iOS中 convertPoint 坐标转换规律

参考:

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

坐标系始终只有一个

frame子视图的origin是相对于父视图的origin来说的。
bounds(改变的是自己的坐标系)子视图的origin 是相对于坐标的坐标系来说的。

view的三个属性bounds frame center 之间的关系

图片 1

C537AC2F-EE12-4A23-BD2D-7EDEDDAC21ED.png

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

我们会看到:紫色view的frame虽然设为,但它的左上角却不在父视图左上角,而是偏离出父视图外面去了

bounds 的使用场景

scrollView 中的原理就是不断改变自己的 bounds.
scrollView不断改变自己的 bounds, 从而改变 scrollView 上的子 View和 frame ,他们的 frame 始终在最顶级 view(window)的 frame 内部,这样就可以始终看到内容.

在 scrollView 的滑动过程中,不断增加 scrollView 的bounds 的 y 值,也就是不断把 scrollView 的本地坐标系原点向下偏移(相对于 scrollView 的父 view 的坐标系, y 值越大,越向下偏移).那么此时 scrollView 的子控件的 frame 设置的(0,0)就是不断向上偏移的

bounds的有以下两个特点:

1. 它可以修改自己坐标系的原点位置,进而影想到“子view”的显示位置。这个作用更像是移动原点的意思。

2. bounds,它可以改变的frame。如果bounds比frame大。那么frame也会跟着变大。这个作用更像边界和大小的意思。

view:(视图):代表屏幕上的一个矩形区域。iOS中的UIView来表示视图。
UI控件都属于view ,iOS中所有能看到的内容都是view或其子类。
超出父视图的范围:仍能显示,但是超出范围的控件无法执行。

输出日志:

图片 2

image

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

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

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

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

图片 3

image

图片 4

image

也许你做ios开发已经有些年了,也许你才刚刚开始加入ios开发大军,大神也好,小白也好,而下面两行代码,也许是我们敲的最想吐的几行代码之一:

总结

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

参考:

[view1 setBounds:CGRectMake(-30, -30, 250, 250)];

添加视图

UIView的addSubview:方法可以添加子视图。
对于同一个视图的所有子视图来讲,后添加的子视图会把已经添加的子视图盖在下面。
UIView提供了其他添加视图的方法:

指定位置插入:insertSubview: atldex:
指定视图上插入:insertSubview: aboveSubview:
指定视图下插入:insertSubview: belowSubview:

输出结果如下:

图片 5

image

 //创建红色view UIView *redView = [[UIView alloc] initWithFrame:CGRectMake(50, 100, 200, 200)]; //打印此时的frame NSLog(@"log1:%@",NSStringFromCGRect(redView.frame)); //设置bounds,x,y分别为20,20,宽高为300,300 redView.bounds = CGRectMake(20, 20, 300, 300); //打印设置完bounds后的frame NSLog(@"log2:%@",NSStringFromCGRect(redView.frame)); redView.backgroundColor = [UIColor redColor]; //把红色view添加到控制器view上 [self.view addSubview:redView];

frame 和 bounds 简介

图片 6

image.png

  • frame: 该 view 在父View 坐标系中的位置和大小.(参照点是,父视图的坐标系)
  • bounds: 该 view 在本地坐标系中的位置和大小.(参照点是,本地坐标系,相当于view 自己的坐标系,以0,0点为起点).

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

参考: 中的示例

通过修改 view 的 bounds 属性可以修改本地坐标系的原点位置,进而影响到子 view 的显示位置

frame就容易理解一些:frame的(frame.origin.x,frame.origin.y)就是相对于父坐标系的偏移量。

bounds稍微有点费解,稍不留神,想的多了,就会绕进去。每个view都有一个本地坐标系统。这个坐标系统作用比较重要,比如触摸的回调函数中的 UITouch里面的>坐标值都是参照这个本地坐标系统的坐标。当然bounds这个属性也是参照这个本地坐标系统来的。

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

通过修改view的bounds属性可以修改本地坐标系统的原点位置。

frame

frame是view的重要属性,视图布局的关键,它决定了视图的大小和位置。
frame是一个结构体,包含两部分内容:origin和size。
origin是一个结构体,包含两部分内容:x和y。
size是一个结构体,包含两部分内容:width和height。
frame的origin和size是相对于俯视图来说的。
CGRectMake() 函数可以帮助我们快速构造一个CGRect变量。

子视图永远是以父视图来作为标准的。

分析

上面设置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。如上图所示。

图片 7imgae1.png

bounds 大于 frame 的情况

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

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

这行代码起到了:让view2的位置改变的作用。为何(-30,-30)的偏移量,却可以让view2向右下角移动呢?

bounds(边界)

Bounds也是view的重要属性,用于定义自己的边界,他同frame一样是一个CGRect结构体变量。
当一个view设置bounds时,会把自己当成一个容器,定义自己的边界大小,以及左上角的初始坐标。
当子视图添加到此视图时,会根据bounds指定的原点(0,0)计算frame,而非左上角。

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));
}

由此我们知道,改变bounds的width和height,不仅会影响frame的width和height(两者的width和height保持一致),还会影响frame的x,y。这种影响是随着bounds的width和height增加或减少,平均扩充或缩减四周的区域。

bounds 的改变会累加

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

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

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

很明显,bounds的原点是(0,0)点(就是view本身的坐标系统,默认永远都是0,0点,除非调用了setbounds函数),而frame的原点却是任意的(相对于父视图中的坐标位置)。

管理视图

把指定的子视图移动到最前面:bringSubviewToFront:
把指定的子视图移动到最后面:bringSubviewToBack:
交换两个指定位置的子视图:exchangeSubviewAtIndex: withSubviewAtIndex:
把receiver从父视图上移除 : removeFromSuperview 子视图自己调用

    //把某个view放到最前面
    [self.view bringSubviewToFront:blueView];
    //把某个view放到最后面
     [self.view sendSubviewToBack:blueView];
    //  交换两个位置的view
      [self.view exchangeSubviewAtIndex:1 withSubviewAtIndex:3];
   //删除某个view
     [blueView removeFromSuperview];

子视图在父视图的上面。若是同层次的谁先被添加,谁在下面。
指定位置的就在相应的位置 ,但是后续操作会改变该视图当前的位置。
但父视图执行的调换,只能控制其子视图的

后面会有详细功能介绍。以及更多的使用方法。如果你喜欢我的文章,并且希望我继续更新,请随意打赏。

bouns大于frame的情况

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

图片 8

image

事实上,你如果不设为,确实有不好的事情发生。我们用如下代码验证:

在iOS开发中经常遇到两个词Frame和bounds,本文主要阐述Frame和bound的区别,尤其是bound很绕,很难理解。

Center

(中心点)也是view的重要属性
center是个结构体,包含两个部分:x和y。
center与frame,有着密切的联系。
Center.x = frame.origin.x + frame.size.width/2;
Center.y = frame.origin.y + frame.size.height/2;

示例代码:

    UIView *view1 = [[UIView alloc] initWithFrame:CGRectMake(200, 200, 100, 100)];
    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));
 self.XXView.frame = CGRectMake(0, 0, 100, 100); self.XXView.bounds = CGRectMake(0, 0, 100, 100);

图片 9

那么如何创建View?
  视图创建代码
UIView *blueView = [[UIView alloc] initWithFrame:CGRectMake(100, 100, 120, 100)];
blueView.backgroundColor = [UIColor blueColor];
[self.view addSubview:blueView];

iOS提供了用于布局的平面坐标系:
左上角为坐标轴的原点。
垂直向下:y 的正方向 屏幕最上到最下可以分为480等份 (3.5寸)
水平向右:为x的正方向 最左到最右可以划分320等份。
坐标系不是以像素作为划分依据,而是以“点”作为依据。

结论

  • 新的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

TAG标签:
版权声明:本文由必威发布于必威-编程,转载请注明出处:本文主要阐述Frame和bound的区别,也许是我们敲的