多多色-多人伦交性欧美在线观看-多人伦精品一区二区三区视频-多色视频-免费黄色视屏网站-免费黄色在线

國(guó)內(nèi)最全I(xiàn)T社區(qū)平臺(tái) 聯(lián)系我們 | 收藏本站
阿里云優(yōu)惠2
您當(dāng)前位置:首頁(yè) > php開(kāi)源 > 綜合技術(shù) > iOS開(kāi)發(fā)——frame和bounds詳解

iOS開(kāi)發(fā)——frame和bounds詳解

來(lái)源:程序員人生   發(fā)布時(shí)間:2016-07-01 15:25:08 閱讀次數(shù):3392次

       在iOS的UI開(kāi)發(fā)中,frame和bounds是兩個(gè)非常容易弄混的概念,而很多開(kāi)發(fā)者在實(shí)際項(xiàng)目中也很少去辨別,因此會(huì)致使出現(xiàn)1些意想不到的問(wèn)題。本篇博客以實(shí)際代碼的方式來(lái)學(xué)習(xí)frame和bounds的使用。相干示例代碼上傳至 https://github.com/chenyufeng1991/FrameAndBounds ,歡迎大家下載查看。

(1)先來(lái)查看1個(gè)界面中的容器self.view的frame和bounds的打印結(jié)果:下面的運(yùn)行結(jié)果都在iPhone5s摹擬器下進(jìn)行。

NSLog(@"self.view.frame = %@",NSStringFromCGRect(self.view.frame)); NSLog(@"self.view.bounds = %@",NSStringFromCGRect(self.view.bounds));

在這里我們可以看到,self.view的frame和bounds是1樣的。原點(diǎn)都是在左上角。長(zhǎng)寬正好是全部屏幕的寬高。


(2)frame和bounds難道都是1樣的嗎?固然不是。現(xiàn)在我們對(duì)1個(gè)View做1個(gè)旋轉(zhuǎn)動(dòng)畫。

UIView *view01 = [[UIView alloc] initWithFrame:CGRectMake(100, 100, 50, 50)]; view01.backgroundColor = [UIColor grayColor]; [self.view addSubview:view01]; NSLog(@"view01.frame = %@",NSStringFromCGRect(view01.frame)); NSLog(@"view01.bounds = %@",NSStringFromCGRect(view01.bounds)); [UIView transitionWithView:view01 duration:2 options:0 animations:^{ view01.transform = CGAffineTransformMakeRotation(M_PI_4); } completion:^(BOOL finished) { if (finished) { NSLog(@"view01.frame = %@",NSStringFromCGRect(view01.frame)); NSLog(@"view01.bounds = %@",NSStringFromCGRect(view01.bounds)); } }];
動(dòng)畫效果以下:

我們讓1個(gè)正方形旋轉(zhuǎn)90度,在動(dòng)畫開(kāi)始前和結(jié)束后分別打印frame和bounds,打印結(jié)果以下:


此時(shí)可以看到,在動(dòng)畫開(kāi)始前,frame和bounds也變得不1樣了。在旋轉(zhuǎn)動(dòng)畫后,frame產(chǎn)生改變,bounds仍然沒(méi)變。我現(xiàn)在告知大家下面的結(jié)論:

-- frame的位置是根據(jù)父容器來(lái)計(jì)算的,正方形在動(dòng)畫開(kāi)始前的x=100,y=100是相對(duì)self.view的坐標(biāo)系統(tǒng)而言的,從而肯定當(dāng)前視圖在父視圖中的位置。

-- bounds的x,y是根據(jù)自己的坐標(biāo)系統(tǒng)而言的。沒(méi)錯(cuò),每一個(gè)view都有自己的坐標(biāo)系。以自己左上角點(diǎn)為坐標(biāo)原點(diǎn)。所以bounds的x,y默許為(0,0),除非調(diào)用setBounds方法;

-- frame的size不1定等于bounds的size,在旋轉(zhuǎn)后它們的size就不1樣了。


在旋轉(zhuǎn)前后,frame產(chǎn)生了較大的變化,其實(shí)旋轉(zhuǎn)后的frame變成了以下:

旋轉(zhuǎn)后:




旋轉(zhuǎn)前:



旋轉(zhuǎn)后,左上角origin的x,y產(chǎn)生了改變,size的height,width也 產(chǎn)生了改變,所以frame也就改變了。我們可以把frame理解為所占區(qū)域,其實(shí)旋轉(zhuǎn)后的占用區(qū)域是產(chǎn)生改變的。但是為何bounds沒(méi)有改變呢?

View在旋轉(zhuǎn)進(jìn)程中,其實(shí)自己的坐標(biāo)系統(tǒng)并沒(méi)有產(chǎn)生改變,bounds中的origin只能通過(guò)setBounds方法修改。 根據(jù)英文中的意思,bounds就是邊界的意思,在旋轉(zhuǎn)進(jìn)程中,View的邊界長(zhǎng)短并沒(méi)有產(chǎn)生改變,所以bounds的size也就沒(méi)有改變。

所以我做個(gè)小小的別名:把frame理解為占用區(qū)域,把bounds理解為邊界。


(3)我們把1個(gè)子View放到父View中,并且改變父View的bounds,來(lái)看看會(huì)產(chǎn)生甚么?

UIView *view02 = [[UIView alloc] initWithFrame:CGRectMake(100, 100, 200, 200)]; view02.backgroundColor = [UIColor colorWithWhite:0.851 alpha:1.000]; [self.view addSubview:view02]; UIView *view02_sub = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 60, 60)]; view02_sub.backgroundColor = [UIColor colorWithRed:1.000 green:0.908 blue:0.552 alpha:1.000]; [view02 addSubview:view02_sub]; [self printFrameAndBounds:view02 viewOfSub:view02_sub]; [UIView animateWithDuration:1 animations:^{ // setBounds 強(qiáng)迫將自己坐標(biāo)系的左上角點(diǎn)改成(⑶0,⑶0)。那末真實(shí)的原點(diǎn)(0,0)自然向右下角偏移(30,30); // 注意:setBounds中的(x,y)只改變自己的坐標(biāo)系統(tǒng)。子view的bounds和frame其實(shí)不會(huì)改變。 [view02 setBounds:CGRectMake(⑶0, ⑶0, 200, 200)]; } completion:^(BOOL finished) { [self printFrameAndBounds:view02 viewOfSub:view02_sub]; }];

打印結(jié)果以下:



運(yùn)行效果圖以下:


我們通過(guò)setBounds把父View的origin=(0,0)改成了(⑶0,⑶0), 發(fā)現(xiàn)子View向右下方產(chǎn)生了移動(dòng)。我們來(lái)分析1下緣由。

我們剛剛提到,setBounds可以改變自己View的坐標(biāo)系,父View強(qiáng)迫把自己左上角的原點(diǎn)(0,0)坐標(biāo)改成了(⑶0,⑶0),但是對(duì)子View.frame.origin=(0,0)來(lái)講,它的x,y沒(méi)有產(chǎn)生改變,依然是(0,0),   由于左上角已改成(⑶0,⑶0),所以真實(shí)的原點(diǎn)(0,0)向右下方移動(dòng),所以子View也就向右下方移動(dòng)了。

做1個(gè)小小的總結(jié):

-- setBounds中的(x,y)只改變自己的坐標(biāo)系統(tǒng),子View的bounds和frame其實(shí)不會(huì)改變;

-- setBounds是修改自己坐標(biāo)系的原點(diǎn)位置,進(jìn)而影響到子View的顯示位置;

-- bounds改變位置時(shí),改變的是子視圖的位置,本身沒(méi)有影響,其實(shí)就是改變了本身的坐標(biāo)系原點(diǎn),默許原點(diǎn)在左上角。


(4)當(dāng)父View的frame改變的時(shí)候,子View會(huì)產(chǎn)生甚么變化?

UIView *view02 = [[UIView alloc] initWithFrame:CGRectMake(100, 100, 200, 200)]; view02.backgroundColor = [UIColor colorWithWhite:0.851 alpha:1.000]; [self.view addSubview:view02]; UIView *view02_sub = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 60, 60)]; view02_sub.backgroundColor = [UIColor colorWithRed:1.000 green:0.908 blue:0.552 alpha:1.000]; [view02 addSubview:view02_sub]; [self printFrameAndBounds:view02 viewOfSub:view02_sub]; [UIView animateWithDuration:1 animations:^{ [view02 setFrame:CGRectMake(0, 250, 150, 150)]; } completion:^(BOOL finished) { [self printFrameAndBounds:view02 viewOfSub:view02_sub]; }];

打印結(jié)果以下:


運(yùn)行效果動(dòng)畫:



從效果圖上可以看到,我們改變了父View的位置和大小(坐標(biāo)系原點(diǎn)依然是(0,0),但是實(shí)際位置已改變了,坐標(biāo)系改變),子View的位置也改變了。但是子View的frame和bounds并沒(méi)有改變。由于子View.origin是相對(duì)父View的而言的,這并沒(méi)有改變。


(5)我們上述都只改變了bounds的位置,而沒(méi)有改變bounds的大小,我們來(lái)看看改變bounds的大小會(huì)產(chǎn)生甚么?

UIView *view02 = [[UIView alloc] initWithFrame:CGRectMake(100, 100, 100, 100)]; view02.backgroundColor = [UIColor colorWithWhite:0.851 alpha:1.000]; [self.view addSubview:view02]; UIView *view02_sub = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 60, 60)]; view02_sub.backgroundColor = [UIColor colorWithRed:1.000 green:0.908 blue:0.552 alpha:1.000]; [view02 addSubview:view02_sub]; [self printFrameAndBounds:view02 viewOfSub:view02_sub]; [UIView animateWithDuration:1 animations:^{ [view02 setBounds:CGRectMake(0, 0, 200, 200)]; } completion:^(BOOL finished) { [self printFrameAndBounds:view02 viewOfSub:view02_sub]; }];

打印結(jié)果以下:


運(yùn)行動(dòng)畫效果以下:


我們使用setBounds方法增大了父View的bounds.size ,可以看到把frame也改變了。所以我做1個(gè)小小的總結(jié):

-- 更改bounds的大小,bounds的大小代表當(dāng)前視圖的長(zhǎng)和寬,修改長(zhǎng)寬后,中心點(diǎn)繼續(xù)保持不變,長(zhǎng)寬進(jìn)行改變,通過(guò)bounds修改長(zhǎng)寬就像是以中心點(diǎn)為基準(zhǔn)點(diǎn)對(duì)長(zhǎng)寬兩邊同時(shí)進(jìn)行縮放。

-- center是根據(jù)父容器的相對(duì)位置來(lái)計(jì)算的,不管是修改父容器的bounds還是本身的bounds,都不會(huì)改變center。況且使用bounds來(lái)縮放view,都是根據(jù)center中心點(diǎn)來(lái)縮放的,所以center不會(huì)改變。

-- setBounds也能夠修改view的大小,進(jìn)而修改frame。


(6)除有setBounds方法,一樣有setFrame方法,我們來(lái)看看使用setFrame改變View的大小會(huì)產(chǎn)生甚么?

UIView *viewFather = [[UIView alloc] initWithFrame:CGRectMake(50, 50, 200, 200)]; viewFather.backgroundColor = [UIColor colorWithWhite:0.741 alpha:1.000]; [self.view addSubview:viewFather]; UIView *viewSub = [[UIView alloc] initWithFrame:CGRectMake(20, 20, 50, 80)]; viewSub.backgroundColor = [UIColor colorWithRed:1.000 green:0.999 blue:0.721 alpha:1.000]; [viewFather addSubview:viewSub];

// (6)修改父視圖的frame的大小。父容器的center改變,子視圖的center不變。 [self printFrameAndBounds:viewFather viewOfSub:viewSub]; [UIView animateWithDuration:3 animations:^{ [viewFather setFrame:CGRectMake(50, 50, 250, 250)]; } completion:^(BOOL finished) { [self printFrameAndBounds:viewFather viewOfSub:viewSub]; }];
打印結(jié)果以下:


動(dòng)畫效果以下:


仔細(xì)視察可以看到,setFrame改變大小和setBounds改變大小是完全不1樣的,setFrame改變長(zhǎng)寬是從左上角原點(diǎn)進(jìn)行縮放的,固定的是原點(diǎn)。而setBounds則固定的是center。

1句話說(shuō):使用frame改變view大小,center改變,由于縮放參考點(diǎn)為左上角。使用bounds改變view大小,center不變,由于縮放參考點(diǎn)為center。


(7)為了上面打印frame,bounds,centre的方便,上面觸及打印父子View方法調(diào)用的printFrameAndBounds方法實(shí)現(xiàn)以下:

- (void)printFrameAndBounds:(UIView *)viewOfFather viewOfSub:(UIView *)viewOfSub { NSLog(@"viewOfFather.frame = %@;viewOfFather.bounds = %@;viewOfFather.center = %@",NSStringFromCGRect(viewOfFather.frame),NSStringFromCGRect(viewOfFather.bounds),NSStringFromCGPoint(viewOfFather.center)); NSLog(@"viewOfSub.frame = %@;viewOfSub.bounds = %@;viewOfSub.center = %@",NSStringFromCGRect(viewOfSub.frame),NSStringFromCGRect(viewOfSub.bounds),NSStringFromCGPoint(viewOfSub.center)); }


     個(gè)人總結(jié)了1下:

-- 如果想修改view的位置而不影響其他,修改本身frame的位置;想修改view的大小,修改frame的大小或bounds的大小(斟酌相對(duì)位置的改變)。

-- 如果想修改view的所有子view的位置,修改view的bounds的位置(父容器坐標(biāo)系)。

     個(gè)人建議,想要查看某個(gè)變量的改變效果,可使用我們初高中實(shí)驗(yàn)中的“單1變量原則”,也就是1次代碼中只改變1個(gè)變量來(lái)運(yùn)行,這樣就可以很方便的知道某個(gè)變量的作用了。具體可以參考Github中的demo。


生活不易,碼農(nóng)辛苦
如果您覺(jué)得本網(wǎng)站對(duì)您的學(xué)習(xí)有所幫助,可以手機(jī)掃描二維碼進(jìn)行捐贈(zèng)
程序員人生
------分隔線----------------------------
分享到:
------分隔線----------------------------
關(guān)閉
程序員人生
主站蜘蛛池模板: 亚洲精品久久久午夜伊人 | 亚洲在线一区二区 | 美国一级大毛片 | 成人国产一区二区三区精品 | 久久精品综合一区二区三区 | 亚洲综合图片 | 日本视频中文字幕一区二区 | 国产一级视频久久 | 亚洲 欧美 国产 中文 | 免费观看欧美一级高清 | 男女啪啪成人免费网站 | 欧美三级午夜理伦三级小说 | 午夜影院免费入口 | 亚洲免费网址 | 成人伊人网 | 中国国产成人精品久久 | 精品日韩在线视频一区二区三区 | 亚洲国产色综合有声小说 | 性做久久久久久免费观看 | 操日本护士 | 日韩免费网站 | 久久视频一区 | 亚洲视屏在线观看 | 国产精品ⅴ视频免费观看 | 337p日本大胆欧美人术艺术精品 | 亚洲国产情侣偷自在线二页 | 特级黄色免费片 | 国产上床视频 | 小说区图片区综合久久88 | 国产欧美日韩在线观看一区二区三区 | 国产大片51精品免费观看 | 国产偷v国产偷v国产 | www.中文字幕在线观看 | 中文字幕第99页 | 日本一区二区不卡在线 | 波多野结衣在线观看网址 | 亚洲国产欧美精品一区二区三区 | 亚洲视频一区在线观看 | 欧洲美女粗暴交视频 | 亚洲图片欧美小说 | 波多野结衣在线观看一区 |