秒懂frame和bounds, 从此以后不迷惑

我们在写bounds的时候通常是self.xxxView.bounds = CGRectMake(0,0,100,100);似乎(x, y)写成(0, 0)是一种习惯, 也是一种比较安全的行为, 因为, 如果改变了(x, y)通常会有无法预知的事情发生, 今天就来探索下, 到底会发生些什么!

1 frame基本用法

    UIView *redView = [[UIView alloc] init];
    redView.backgroundColor = UIColor.redColor;
    redView.frame = CGRectMake(0, 0, 200, 200);
    [self.view addSubview:redView];
图1

没有什么好说的, 大家都知道结果会是这样

2初级用法

    UIView *redView = [[UIView alloc] init];
    redView.backgroundColor = UIColor.redColor;
    redView.bounds = CGRectMake(0, 0, 200, 200);
    [self.view addSubview:redView];
图2

看到了吗? 在不设置frame的情况下, 只设置bounds, 会让redView的中心点和self.view的起始点重合, 这里不得不说一下锚点:

一个view的layer是有anchorPoint的, 默认情况下, anchorPoint是(0.5, 0.5), 也就是在这个view的中点. 当addSubview(如果仅仅设置了bounds)的时候, 会让锚点和父view的起始点重合, 这也就解释了为什么会出现图2的情况. 我想对于单独使用bounds出现的结果, 我已经解释清楚了.

3中级用法

    [super viewDidLoad];
    UIView *redView = [[UIView alloc] init];
    redView.backgroundColor = UIColor.redColor;
    redView.frame = CGRectMake(0, 0, 200, 200);
    redView.bounds = CGRectMake(-100, -100, 200, 200);
    [self.view addSubview:redView];
    
    UIView *blueView = [[UIView alloc] init];
    blueView.backgroundColor = UIColor.blueColor;
    blueView.frame = CGRectMake(0, 0, 100, 100);
    [redView addSubview:blueView];

这里已经把redView 的frame设置在了(0,0,200,200) 然后又设置了bounds, 但是不改变width和height

图3

这种情况, (-100, -100) 相当于把redView的坐标系, 也就是redView的子view(这里就是blueView了)的起始点向右下移动(100, 100), 这里的减号表示方向, point的第一个参数是左右移动, 第二个是上下移动, so, 此时蓝色view认为父view(红色view)的起始点在整个坐标系的(100, 100)位置. 所以此时设置蓝色view的frame会出现在图3的位置.

4高级用法

    UIView *redView = [[UIView alloc] init];
    redView.backgroundColor = UIColor.redColor;
    redView.frame = CGRectMake(0, 0, 200, 200);
    redView.bounds = CGRectMake(-100, -100, 300, 300);
    [self.view addSubview:redView];

此时通过给redView设置bounds, 不仅改变(x, y)还改变(width, height)这时候会出现什么结果呢?

图4

输出一下redView的frame

{{-50, -50}, {300, 300}}

起始点变成了(-50, -50)
输出下anchorPoint

{0.5, 0.5}

锚点没变, 但是起点变了. 说好的anchorPoint和起点重合呢? 喂, 现在不是单纯的设置bounds啊, 你设置了frame了好不啦! 为什么会出现这种情况呢? 小编认为, 在单纯通过设置bounds的情况下, 锚点的绝对坐标应该是{0, 0}, 但是现在先设置了frame又重置了bounds的宽高(注意, 这里bounds的x,y不会影响到redView的显示), 那增加的宽高如何分配呢? 总之宽高都不能变, 还是{300, 300}, 那就确定锚点的绝对坐标就行了, 锚点最初因为设置frame(0,0,200, 200), 所以锚点的绝对坐标在{100, 100}, 因为锚点的绝对坐标是不会变的, 所以frame的范围是{100-300/2, 100+300/2}={-50,250}, 所以frame={{-50, -50}, {300, 300}}

5终极玩法

    UIView *redView = [[UIView alloc] init];
    redView.backgroundColor = UIColor.redColor;
    redView.frame = CGRectMake(20, 20, 200, 200);
    redView.bounds = CGRectMake(0, 0, 300, 300);
    [self.view addSubview:redView];

如果说高级玩法还勉强可以接受的话, 那终极玩法纯粹是作死啊, 已经设置了frame, 然而frame并不在整个view的起点, 因为锚点(0.5, 0.5), 通过frame确定中心点, 为(120, 120), 因为锚点不动, 所以frame的范围是{120-150, 120+150}, 所以frame={{-30, -30}, {300, 300}}
看下结果

图5

总结:

1 设置了bounds的(x, y)相当于给子view一个起点, 其中, 减号表示向正方向偏移.
2 单纯设置bounds显示出来的view的位置和锚点有关.
3 通过先设置frame再设置bounds的做法在实际开发中没任何意义. 要知道真实frame的绝对位置, 需要通过锚点确定的原中心点的绝对位置, 然后保持中心点位置不变, 根据大小就能确定起始点了.
4 先设置bounds再设置frame, 以frame值为最终view的frame.

思考

    UIView *redView = [[UIView alloc] init];
    redView.backgroundColor = UIColor.redColor;
    redView.frame = CGRectMake(20, 20, 200, 200);
    redView.bounds = CGRectMake(0, 0, 100, 100);
    [self.view addSubview:redView];

这个redView的frame是多少呢?

答案:

{{70, 70}, {100, 100}}

解读:

frame(20, 20, 200, 200)和anchorPoint(0.5, 0.5), 确定了中心点的绝对位置 20+200*0.5 = 120, 因为锚点不动, 所以frame的范围是{120-50, 120+50}, 所以frame={{70, 70}, {100, 100}}.

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,491评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,856评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,745评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,196评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,073评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,112评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,531评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,215评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,485评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,578评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,356评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,215评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,583评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,898评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,174评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,497评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,697评论 2 335

推荐阅读更多精彩内容

  • 1 CALayer IOS SDK详解之CALayer(一) http://doc.okbase.net/Hell...
    Kevin_Junbaozi阅读 5,088评论 3 23
  • 在iOS实际开发中常用的动画无非是以下四种:UIView动画,核心动画,帧动画,自定义转场动画。 1.UIView...
    请叫我周小帅阅读 3,053评论 1 23
  • 在iOS实际开发中常用的动画无非是以下四种:UIView动画,核心动画,帧动画,自定义转场动画。下面我们逐个介绍。...
    4b5cb36a2ee2阅读 347评论 0 0
  • 在iOS中随处都可以看到绚丽的动画效果,实现这些动画的过程并不复杂,今天将带大家一窥ios动画全貌。在这里你可以看...
    每天刷两次牙阅读 8,418评论 6 30
  • 在iOS中随处都可以看到绚丽的动画效果,实现这些动画的过程并不复杂,今天将带大家一窥iOS动画全貌。在这里你可以看...
    F麦子阅读 5,066评论 5 13