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

我們?cè)趯慴ounds的時(shí)候通常是self.xxxView.bounds = CGRectMake(0,0,100,100);似乎(x, y)寫成(0, 0)是一種習(xí)慣, 也是一種比較安全的行為, 因?yàn)? 如果改變了(x, y)通常會(huì)有無法預(yù)知的事情發(fā)生, 今天就來探索下, 到底會(huì)發(fā)生些什么!

1 frame基本用法

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

沒有什么好說的, 大家都知道結(jié)果會(huì)是這樣

2初級(jí)用法

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

看到了嗎? 在不設(shè)置frame的情況下, 只設(shè)置bounds, 會(huì)讓redView的中心點(diǎn)和self.view的起始點(diǎn)重合, 這里不得不說一下錨點(diǎn):

一個(gè)view的layer是有anchorPoint的, 默認(rèn)情況下, anchorPoint是(0.5, 0.5), 也就是在這個(gè)view的中點(diǎn). 當(dāng)addSubview(如果僅僅設(shè)置了bounds)的時(shí)候, 會(huì)讓錨點(diǎn)和父view的起始點(diǎn)重合, 這也就解釋了為什么會(huì)出現(xiàn)圖2的情況. 我想對(duì)于單獨(dú)使用bounds出現(xiàn)的結(jié)果, 我已經(jīng)解釋清楚了.

3中級(jí)用法

    [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];

這里已經(jīng)把redView 的frame設(shè)置在了(0,0,200,200) 然后又設(shè)置了bounds, 但是不改變width和height

圖3

這種情況, (-100, -100) 相當(dāng)于把redView的坐標(biāo)系, 也就是redView的子view(這里就是blueView了)的起始點(diǎn)向右下移動(dòng)(100, 100), 這里的減號(hào)表示方向, point的第一個(gè)參數(shù)是左右移動(dòng), 第二個(gè)是上下移動(dòng), so, 此時(shí)藍(lán)色view認(rèn)為父view(紅色view)的起始點(diǎn)在整個(gè)坐標(biāo)系的(100, 100)位置. 所以此時(shí)設(shè)置藍(lán)色view的frame會(huì)出現(xiàn)在圖3的位置.

4高級(jí)用法

    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];

此時(shí)通過給redView設(shè)置bounds, 不僅改變(x, y)還改變(width, height)這時(shí)候會(huì)出現(xiàn)什么結(jié)果呢?

圖4

輸出一下redView的frame

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

起始點(diǎn)變成了(-50, -50)
輸出下anchorPoint

{0.5, 0.5}

錨點(diǎn)沒變, 但是起點(diǎn)變了. 說好的anchorPoint和起點(diǎn)重合呢? 喂, 現(xiàn)在不是單純的設(shè)置bounds啊, 你設(shè)置了frame了好不啦! 為什么會(huì)出現(xiàn)這種情況呢? 小編認(rèn)為, 在單純通過設(shè)置bounds的情況下, 錨點(diǎn)的絕對(duì)坐標(biāo)應(yīng)該是{0, 0}, 但是現(xiàn)在先設(shè)置了frame又重置了bounds的寬高(注意, 這里bounds的x,y不會(huì)影響到redView的顯示), 那增加的寬高如何分配呢? 總之寬高都不能變, 還是{300, 300}, 那就確定錨點(diǎn)的絕對(duì)坐標(biāo)就行了, 錨點(diǎn)最初因?yàn)樵O(shè)置frame(0,0,200, 200), 所以錨點(diǎn)的絕對(duì)坐標(biāo)在{100, 100}, 因?yàn)殄^點(diǎn)的絕對(duì)坐標(biāo)是不會(huì)變的, 所以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];

如果說高級(jí)玩法還勉強(qiáng)可以接受的話, 那終極玩法純粹是作死啊, 已經(jīng)設(shè)置了frame, 然而frame并不在整個(gè)view的起點(diǎn), 因?yàn)殄^點(diǎn)(0.5, 0.5), 通過frame確定中心點(diǎn), 為(120, 120), 因?yàn)殄^點(diǎn)不動(dòng), 所以frame的范圍是{120-150, 120+150}, 所以frame={{-30, -30}, {300, 300}}
看下結(jié)果

圖5

總結(jié):

1 設(shè)置了bounds的(x, y)相當(dāng)于給子view一個(gè)起點(diǎn), 其中, 減號(hào)表示向正方向偏移.
2 單純?cè)O(shè)置bounds顯示出來的view的位置和錨點(diǎn)有關(guān).
3 通過先設(shè)置frame再設(shè)置bounds的做法在實(shí)際開發(fā)中沒任何意義. 要知道真實(shí)frame的絕對(duì)位置, 需要通過錨點(diǎn)確定的原中心點(diǎn)的絕對(duì)位置, 然后保持中心點(diǎn)位置不變, 根據(jù)大小就能確定起始點(diǎn)了.
4 先設(shè)置bounds再設(shè)置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];

這個(gè)redView的frame是多少呢?

答案:

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

解讀:

frame(20, 20, 200, 200)和anchorPoint(0.5, 0.5), 確定了中心點(diǎn)的絕對(duì)位置 20+200*0.5 = 120, 因?yàn)殄^點(diǎn)不動(dòng), 所以frame的范圍是{120-50, 120+50}, 所以frame={{70, 70}, {100, 100}}.

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容

  • 1 CALayer IOS SDK詳解之CALayer(一) http://doc.okbase.net/Hell...
    Kevin_Junbaozi閱讀 5,207評(píng)論 3 23
  • 在iOS實(shí)際開發(fā)中常用的動(dòng)畫無非是以下四種:UIView動(dòng)畫,核心動(dòng)畫,幀動(dòng)畫,自定義轉(zhuǎn)場動(dòng)畫。 1.UIView...
    請(qǐng)叫我周小帥閱讀 3,155評(píng)論 1 23
  • 在iOS實(shí)際開發(fā)中常用的動(dòng)畫無非是以下四種:UIView動(dòng)畫,核心動(dòng)畫,幀動(dòng)畫,自定義轉(zhuǎn)場動(dòng)畫。下面我們逐個(gè)介紹。...
    4b5cb36a2ee2閱讀 370評(píng)論 0 0
  • 在iOS中隨處都可以看到絢麗的動(dòng)畫效果,實(shí)現(xiàn)這些動(dòng)畫的過程并不復(fù)雜,今天將帶大家一窺ios動(dòng)畫全貌。在這里你可以看...
    每天刷兩次牙閱讀 8,566評(píng)論 6 30
  • 在iOS中隨處都可以看到絢麗的動(dòng)畫效果,實(shí)現(xiàn)這些動(dòng)畫的過程并不復(fù)雜,今天將帶大家一窺iOS動(dòng)畫全貌。在這里你可以看...
    F麥子閱讀 5,141評(píng)論 5 13