首先,我們來看一下iOS特有的坐標(biāo)系,在iOS坐標(biāo)系中以左上角為坐標(biāo)原點(diǎn),往右為X正方向饮亏,往下是Y正方向如下圖:
bounds和frame都是屬于CGRect類型的結(jié)構(gòu)體,系統(tǒng)的定義如下峭状,包含一個(gè)CGPoint(起點(diǎn))和一個(gè)CGSize(尺寸)子結(jié)構(gòu)體克滴。
struct CGRect {
CGPoint origin;
CGSize size;
};
復(fù)制代碼
origin決定了view的起點(diǎn),size決定View的尺寸优床。
1.frame
frame是每個(gè)view必備的屬性,表示view在父view坐標(biāo)系統(tǒng)中的位置和大小誓焦,參照點(diǎn)是父視圖的坐標(biāo)系統(tǒng)胆敞。
示例代碼:
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));
復(fù)制代碼
打印結(jié)果:
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}}
復(fù)制代碼
效果圖:
以上可以看出,viewB和viewC的起點(diǎn)重合杂伟,但是從打印結(jié)果來看移层,viewB的起點(diǎn)為(50,50),而viewCde起點(diǎn)為(100,100)赫粥。原因就是frame中的位置是以父視圖的坐標(biāo)系為標(biāo)準(zhǔn)來確定當(dāng)前視圖的位置观话,viewB的父視圖為viewA,viewC的父視圖為self.view越平,而由于viewA的起點(diǎn)為(50,50)频蛔,所以viewB與viewC起點(diǎn)才會(huì)重合。
2.bounds
bounds也是每個(gè)view都有的屬性秦叛,這個(gè)屬性我們一般不進(jìn)行設(shè)置晦溪,表示view在本地坐標(biāo)系統(tǒng)中的位置和大小。參照點(diǎn)是本地坐標(biāo)系統(tǒng)挣跋。如果我們對(duì)上例打印bounds三圆,將會(huì)得到以下結(jié)果:
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}}
復(fù)制代碼
因?yàn)槲覀儾]有設(shè)置bounds值,那么,bounds到底有什么作用呢舟肉。這里強(qiáng)調(diào)修噪,每個(gè)視圖都有自己的坐標(biāo)系,且這個(gè)坐標(biāo)系默認(rèn)以自身的左上角為坐標(biāo)原點(diǎn)路媚,所有子視圖以這個(gè)坐標(biāo)系的原點(diǎn)為基準(zhǔn)點(diǎn)黄琼。bounds的位置代表的是子視圖看待當(dāng)前視圖左上角的位置,bounds的大小代表當(dāng)前視圖的大小磷籍。原則如下:
- 更改bounds中的位置對(duì)于當(dāng)前視圖沒有影響适荣,相當(dāng)于更改了當(dāng)前視圖的坐標(biāo)系,對(duì)于子視圖來說當(dāng)前視圖的左上角已經(jīng)不再是(0,0)院领, 而是改變后的坐標(biāo)弛矛,坐標(biāo)系改了,那么所有子視圖的位置也會(huì)跟著改變比然。
- 更改bounds的大小丈氓,bounds的大小代表當(dāng)前視圖的長(zhǎng)和寬,修改長(zhǎng)寬后强法,中心點(diǎn)繼續(xù)保持不變万俗, 長(zhǎng)寬進(jìn)行改變,通過bounds修改長(zhǎng)寬看起來就像是以中心點(diǎn)為基準(zhǔn)點(diǎn)對(duì)長(zhǎng)寬兩邊同時(shí)進(jìn)行縮放饮怯。
以下給出例子詳細(xì)討論闰歪。
3.兩者的區(qū)別
3.1 origin的區(qū)別
如下圖:
此時(shí),如果我們把ViewA的bounds改為(0,100)蓖墅,結(jié)果如下:
我們始終要清楚库倘,bounds的位置代表的是子視圖看待當(dāng)前視圖左上角的位置。 bounds遵守的原則一中论矾,更改bounds中的位置對(duì)于當(dāng)前視圖(ViewA)沒有影響教翩,相當(dāng)于更改了ViewA的坐標(biāo)系,但是子視圖(ViewB)不同贪壳,對(duì)于ViewB來說ViewA的左上角已經(jīng)不再是(0,0)饱亿, 而是(0,100),所以對(duì)于ViewB來說闰靴,ViewA坐標(biāo)系的原點(diǎn)其實(shí)是在紅色箭頭所指處的上方100處彪笼,而此時(shí)ViewB的frame.origin為(200,100),所以ViewB的上邊與ViewA上邊重合传黄。
如果我們更改ViewA的bounds為(200,0)杰扫,同理(可以自己思考試試),結(jié)果如下:
3.2 size的區(qū)別
frame的size直接決定了view的大小膘掰,而bounds的size修改后章姓,view的中心點(diǎn)不變佳遣,長(zhǎng)寬以中心點(diǎn)進(jìn)行縮放。
如下例:
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設(shè)置size(320,160)
[viewB setBounds:CGRectMake(0, 0, 320, 240)];
復(fù)制代碼
結(jié)果如下:
第二個(gè)圖為設(shè)置了size之后的結(jié)果凡伊,viewB左上點(diǎn)距離viewA顯然不為(100,50)零渐,而是進(jìn)行了基于viewB視圖中心點(diǎn)的縮放操作。
4.總結(jié)
- frame不管對(duì)于位置還是大小系忙,改變的都是自己本身诵盼。
- frame的位置是以父視圖的坐標(biāo)系為參照,從而確定當(dāng)前視圖在父視圖中的位置银还。
- frame的大小改變時(shí)风宁,當(dāng)前視圖的左上角位置不會(huì)發(fā)生改變,只是大小發(fā)生改變蛹疯。
- bounds改變位置時(shí)戒财,改變的是子視圖的位置,自身沒有影響捺弦;其實(shí)就是改變了本身的坐標(biāo)系原點(diǎn)饮寞,默認(rèn)本身坐標(biāo)系的原點(diǎn)是左上角。
- bounds的大小改變時(shí)列吼,當(dāng)前視圖的中心點(diǎn)不會(huì)發(fā)生改變幽崩,當(dāng)前視圖的大小發(fā)生改變,看起來效果就想縮放一樣寞钥。