相信你們學習iOS視圖部分的時候,跟它倆沒少糾纏,尤爲是bounds不少朋友都糊了,bounds確實比較難理解。這兩個概念很重要,由於它們是奠基整個視圖層次結構的基礎。因此咱們須要瞭解的透徹一點。源代碼git
首先,咱們來看一下iOS特有的座標系,在iOS座標系中以左上角爲座標原點,往右爲X正方向,往下是Y正方向以下圖:github
bounds和frame都是屬於CGRect類型的結構體,系統的定義以下,包含一個CGPoint(起點)和一個CGSize(尺寸)子結構體。學習
struct CGRect {
CGPoint origin;
CGSize size;
};
複製代碼
origin決定了view的起點,size決定View的尺寸。spa
frame是每一個view必備的屬性,表示view在父view座標系統中的位置和大小,參照點是父視圖的座標系統。code
示例代碼:cdn
UIView *viewA = [[UIView alloc] initWithFrame:CGRectMake(50, 50, 300, 300)];
[viewA setBackgroundColor:[UIColor blueColor]];
[self.view addSubview:viewA];
NSLog(@"viewA - %@",NSStringFromCGRect(viewA.frame));
UIView *viewB = [[UIView alloc] initWithFrame:CGRectMake(50, 50, 200, 200)];
[viewB setBackgroundColor:[UIColor yellowColor]];
[viewA addSubview:viewB];
NSLog(@"viewB - %@",NSStringFromCGRect(viewB.frame));
UIView *viewC = [[UIView alloc] initWithFrame:CGRectMake(100, 100, 100, 100)];
[viewC setBackgroundColor:[UIColor redColor]];
[self.view addSubview:viewC];
NSLog(@"viewC - %@",NSStringFromCGRect(viewC.frame));
複製代碼
打印結果:blog
2018-01-14 21:35:16.196389+0800 frame & bounds[1485:121325] viewA - {{50, 50}, {300, 300}}
2018-01-14 21:35:16.196647+0800 frame & bounds[1485:121325] viewB - {{50, 50}, {200, 200}}
2018-01-14 21:35:16.196802+0800 frame & bounds[1485:121325] viewC - {{100, 100}, {200, 200}}
複製代碼
效果圖:get
以上能夠看出,viewB和viewC的起點重合,可是從打印結果來看,viewB的起點爲(50,50),而viewCde起點爲(100,100)。緣由就是frame中的位置是以父視圖的座標系爲標準來肯定當前視圖的位置,viewB的父視圖爲viewA,viewC的父視圖爲self.view,而因爲viewA的起點爲(50,50),因此viewB與viewC起點纔會重合。it
bounds也是每一個view都有的屬性,這個屬性咱們通常不進行設置,表示view在本地座標系統中的位置和大小。參照點是本地座標系統。若是咱們對上例打印bounds,將會獲得如下結果:io
2018-01-14 22:03:44.385207+0800 frame & bounds[1635:140821] viewA - {{0, 0}, {300, 300}}
2018-01-14 22:03:44.385482+0800 frame & bounds[1635:140821] viewB - {{0, 0}, {200, 200}}
2018-01-14 22:03:44.385646+0800 frame & bounds[1635:140821] viewC - {{0, 0}, {100, 100}}
複製代碼
由於咱們並無設置bounds值,那麼,bounds到底有什麼做用呢。這裏強調,每一個視圖都有本身的座標系,且這個座標系默認以自身的左上角爲座標原點,全部子視圖以這個座標系的原點爲基準點。bounds的位置表明的是子視圖看待當前視圖左上角的位置,bounds的大小表明當前視圖的大小。原則以下:
如下給出例子詳細討論。
以下圖:
此時,若是咱們把ViewA的bounds改成(0,100),結果以下:
咱們始終要清楚,bounds的位置表明的是子視圖看待當前視圖左上角的位置。 bounds遵照的原則一中,更改bounds中的位置對於當前視圖(ViewA)沒有影響,至關於更改了ViewA的座標系,可是子視圖(ViewB)不一樣,對於ViewB來講ViewA的左上角已經再也不是(0,0), 而是(0,100),因此對於ViewB來講,ViewA座標系的原點實際上是在紅色箭頭所指處的上方100處,而此時ViewB的frame.origin爲(200,100),因此ViewB的上邊與ViewA上邊重合。
若是咱們更改ViewA的bounds爲(200,0),同理(能夠本身思考試試),結果以下:
frame的size直接決定了view的大小,而bounds的size修改後,view的中心點不變,長寬以中心點進行縮放。
以下例:
UIView *viewA = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 240)];
[viewA setBackgroundColor:[UIColor grayColor]];
[self.view addSubview:viewA];
UIView *viewB = [[UIView alloc] initWithFrame:CGRectMake(100, 50, 160, 120)];
[viewB setBackgroundColor:[UIColor blueColor]];
[viewA addSubview:viewB];
//viewB設置size(320,160)
[viewB setBounds:CGRectMake(0, 0, 320, 240)];
複製代碼
結果以下:
第二個圖爲設置了size以後的結果,viewB左上點距離viewA顯然不爲(100,50),而是進行了基於viewB視圖中心點的縮放操做。