文章目錄
- 前言
- frame
- bounds
- 兩者區別
- size的區別
- 總結
前言
在學習響應者鏈的過程中用到了frame與bounds的混用,這兩個屬性經常出現在我們的開發中,特別撰寫一篇博客分析區別
首先,我們來看一下iOS特有的坐標系,在iOS坐標系中以左上角為坐標原點,往右為X正方向,往下是Y正方向如下圖:
我們來看一下frame與bounds在文件中的定義
bounds
默認邊界為原點0,frame大小。可以做成動畫
frame
可以做成動畫。如果視圖被轉換,不要使用frame,因為它不能正確反映視圖的實際位置。使用bounds + center代替
。
同時可以看到他們都是CGRect
結構體
struct CGRect {CGPoint origin;CGSize size;
};
origin
決定了view
的起點,size
決定View
的尺寸
frame
frame
描述的是視圖相對于它的父視圖的坐標系統中的位置和大小。它包含一個CGRect
值,定義視圖的原點位置和寬高。
- 坐標系:父視圖的坐標系。
- 內容:包含視圖的原點相對于父視圖的位置,以及視圖的寬度和高度。
- 應用:適合在父視圖中設置視圖的位置和大小。
來看一段Demo
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));
輸出:
以上可以看出,viewB和viewC的起點重合
但是從打印結果來看,viewB的起點為(50,50),而viewC的起點為(100,100)。
原因就是frame中的位置是以父視圖的坐標系為標準來確定當前視圖的位置
viewB的父視圖為viewA,viewC的父視圖為self.view,而由于viewA的起點為(50,50),所以viewB與viewC起點才會重合。
bounds
我們再打印一下bounds
UIView *viewA = [[UIView alloc] initWithFrame:CGRectMake(50, 50, 300, 300)];[viewA setBackgroundColor:[UIColor blueColor]];[self.view addSubview:viewA];NSLog(@"viewA - %@",NSStringFromCGRect(viewA.bounds));UIView *viewB = [[UIView alloc] initWithFrame:CGRectMake(50, 50, 200, 200)];[viewB setBackgroundColor:[UIColor yellowColor]];[viewA addSubview:viewB];NSLog(@"viewB - %@",NSStringFromCGRect(viewB.bounds));UIView *viewC = [[UIView alloc] initWithFrame:CGRectMake(100, 100, 100, 100)];[viewC setBackgroundColor:[UIColor redColor]];[self.view addSubview:viewC];NSLog(@"viewC - %@",NSStringFromCGRect(viewC.bounds));
可以看到bounds的起點都是0
這也符合文檔中的說明默認邊界為原點0,frame大小。可以做成動畫
每個視圖都有自己的坐標系,且這個坐標系默認以自身的左上角為坐標原點,所有子視圖以這個坐標系的原點為基準點。
bounds
的位置代表的是子視圖看待當前視圖左上角的位置,bounds
的大小代表當前視圖的大小。
- 修改frame會改變視圖在父視圖中的位置。
- 修改bounds不會改變視圖在父視圖中的位置,只會改變其內部內容的繪制區域,也就是會改變子視圖的位置、
兩者區別
此時,如果我們把ViewA
的bounds
改為(0,100),結果如下:
此時父視圖左上角不再是(0,0),而是(0,50),因此子視圖才會往上移動
size的區別
frame的size直接決定了view的大小,而bounds的size修改后,view的中心點不變,長寬以中心點進行縮放
。
看Demo:
UIView *viewA = [[UIView alloc] initWithFrame:CGRectMake(50, 50, 300, 300)];[viewA setBackgroundColor:[UIColor blueColor]];viewA.bounds = CGRectMake(50, 50, 300, 300);[self.view addSubview:viewA];NSLog(@"viewA - %@",NSStringFromCGRect(viewA.bounds));
修改bounds為CGRectMake(50, 50, 100, 100)
中心點沒變,只是中心點進行了縮放
總結
坐標系不同:
frame
:父視圖坐標系,用于確定視圖在父視圖中的位置。
bounds
:自身坐標系,用于描述視圖內容區域的布局。
位置與布局:
frame
用于確定視圖在父視圖中的整體位置和大小。
bounds
修改origal自身不變化,會影響子視圖,修改size以自身中心點進行縮放
參考博客:frame與bounds的區別詳解