iOS和Android在UI佈局上最大的不同點就是iOS有座標,座標可以幫助開發者精確的定位,但是隨著apple產品的螢幕尺寸多樣化,座標就不再好用。像是這個網頁提到的,目前光是座標就有4種不同大小。
好在apple推出了size class和auto layout協助開發者處理座標上的差異,不過這些工具依然沒有辦法將所有的UI做到等比例縮放,因為他們的定位基本上還是建立在座標之上。要做到將UI在不同大小的螢幕上等比例縮放,甚至在旋轉後還能等比例縮放我目前知道的唯一辦法就是用程式寫。
之前我用程式寫,在程式中有許多計算比例的算式和CGRectMake...導致可讀性降低,比較好的處理方式是將計算位置的方法寫在方法裡面,我們可以用上次提到的Category,實作一個UIView Category加入計算的方法,或是直接寫個物件方法或是函示(C Function),解決的方法很多種,難度也不高。之所以寫在這個網誌是要提醒自己,不要在程式中遺留ㄧ堆計算位置的code,程式亂到我自己看都會怕。
開始看程式碼之前,先看看執行的效果,不管螢幕的尺寸改變或是旋轉螢幕,這些View相對於superView的長寬比例都不會改變。
如果用C寫的話可以參考以下的程式碼:
這個函示需要兩個參數:
第一個是superView,要計算UIView在superView中的相對位置需要superView的size。
第二的參數是一個CGRect,我用一個CGRect的結構來表達UIView.frame之於superView的比例。
#pragma mark Function
CGRect layoutInSuperViewwithRatios(UIView * superView, CGRect rectRatios){
CGSize superViewSize = superView.bounds.size;
CGFloat originX = rectRatios.origin.x*superViewSize.width;
CGFloat originY = rectRatios.origin.y*superViewSize.height;
CGFloat width = rectRatios.size.width * superViewSize.width;
CGFloat height = rectRatios.size.height * superViewSize.height;
return CGRectMake(originX, originY, width, height);
}
或者選擇用 Category可以在檔案的開頭寫下以下的程式碼:計算的方式基本上和上面介紹的函示一模一樣。
#pragma mark Category
@implementation UIView (RelativeLayout)
+(CGRect)relativeLayoutinView:(UIView*)superView ratios:(CGRect)rectRatios{
CGSize superViewSize = superView.bounds.size;
CGFloat originX = rectRatios.origin.x*superViewSize.width;
CGFloat originY = rectRatios.origin.y*superViewSize.height;
CGFloat width = rectRatios.size.width * superViewSize.width;
CGFloat height = rectRatios.size.height * superViewSize.height;
CGRectMake(originX, originY, width, height);
return CGRectMake(originX, originY, width, height);
}
@end
接下來就是ViewController部分的程式碼:
為了方便,我將這些UIView都宣告為物件變數,我在viewDidLoad方法中將這些UIView實體化,然後在viewWillLayoutSubviews方法中計算他們的位置和長寬。為了Demo前兩個View用了函示後兩個View用了類別方法,但基本上作用一模一樣,甚至你想把類別方法直接改成物件方法也行。
#pragma mark ViewController
@interface ViewController ()
{
UIView * testView1, * testView2, * testView3, * testView4;
}
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
testView1 = [[UIView alloc]init];
testView1.backgroundColor = [UIColor darkGrayColor];
[self.view addSubview:testView1];
testView2 = [[UIView alloc]init];
testView2.backgroundColor = [UIColor blueColor];
[self.view addSubview:testView2];
testView3 = [[UIView alloc]init];
testView3.backgroundColor = [UIColor redColor];
[self.view addSubview:testView3];
testView4 = [[UIView alloc]init];
testView4.backgroundColor = [UIColor yellowColor];
[self.view addSubview:testView4];
}
-(void)viewWillLayoutSubviews{
[super viewWillLayoutSubviews];
testView1.frame = layoutInSuperViewwithRatios(self.view,(CGRect){0.1,0.1,0.4,0.9});
testView2.frame = layoutInSuperViewwithRatios(self.view,(CGRect){0.5,0.1,0.4,0.4});
testView3.frame = [UIView relativeLayoutinView:self.view ratios:(CGRect){0.5,0.5,0.4,0.25}];
testView4.frame = [UIView relativeLayoutinView:self.view ratios:(CGRect){0.5,0.75,0.4,0.25}];
}
@end
結論:計算UI位置的方式百百種,重要的是提高程式的可讀性,往後在維護時不會一頭霧水。使用時機:UI設計師出的設計圖只給比例不給座標或是懶得用storyboard or Xib時。


有幫助!
回覆刪除