標籤:auto layout ios constraints constant multiplier
上一篇講了IOS中基礎的距離單位,連結為 IOS介面適配一: Pt與Px的關係 ,使用距離單位可以定義我們程式中View的大小,但是,僅僅使用Pt定義大小是遠遠不夠的。
比如,我們想讓一個button距離手機左邊界為20pt,右邊界為20pt,距上為30pt,高度自身為20pt,如果在iphone5中(為320pt*568pt),我們要在代碼中這麼定義
以下代碼寫在ViewController中的viewDidLoad方法中:
UIButton * button = [[UIButton alloc]initWithFrame:CGRectMake(20, 30, 280, 20)]; [button setTitle:@"hello pt" forState:UIControlStateNormal]; [button setBackgroundColor:[UIColor grayColor]]; [self.view addSubview:button];
因為iphone5為320pt,所以這個button的寬度必須是280pt好了,看一下效果:
恩,看起來還符合要求,轉一下試試呢:
等等,怎麼跟設想的不一樣呢?這是因為,我們在設定button的時候,就只考慮了Iphone5這個尺寸下的橫屏,ios傳統方法在判斷view位置的時候,先看這個View在父View所載的位置,在看View本身的大小,所以,如果要是按我們剛開始的條件的話,button在父View的位置為(20,30) 大小為(280,20),但是當我們橫屏的時候,父View變了,但button在父View的位置沒變,大小也沒變,才會出現這種情況
還有一種情況,我們換一個不同的解析度的手機會怎麼樣:
可以看出,在Iphone6下就完全不對了,這是因為父View的大小變了,根據iphone5算出來的大小肯定會出錯
上述說的是傳統的限制View位置和大小的方法,需要注意的是:
當我們開啟一個布局檔案,並在裡面拖動進控制項的時候,或者在代碼中使用initWithFrame方法的時候,都是使用的預設的傳統限制方法,也就是上面的方法
雖然說這種方法簡單,易懂,但是用起來局限性非常之大,幾乎只能算是在iphone解析度不變的時候用一下(那時候很多工程都不用布局檔案,只用純程式碼寫),但在現在iphone解析度多達4種,而且有的時候還要求支援橫屏,使用上述方法可以說是寸步難行,下面我們使用Auto Layout解決上述問題
一.在布局檔案中使用Auto Layout
先來看看apple官方對於Auto Layout的解釋:
AutoLayout是一種基於約束的,描述性的布局系統。
關鍵詞:
- 基於約束 - 和以往定義frame的位置和尺寸不同,AutoLayout的位置確定是以所謂相對位置的約束來定義的,比如x座標為superView的中心,y座標為螢幕底部上方10像素等
- 描述性 - 約束的定義和各個view的關係使用接近自然語言或者可視化語言的方法來進行描述
- 布局系統 - 即字面意思,用來負責介面的各個元素的位置。
總而言之,AutoLayout為開發人員提供了一種不同於傳統對於UI元素位置指定的布局方法。以前,不論是在IB裡拖放,還是在代碼中寫,每個UIView都會有自己的frame屬性,來定義其在當前視圖中的位置和尺寸。使用AutoLayout的話,就變為了使用約束條件來定義view的位置和尺寸。這樣的最大好處是一舉解決了不同解析度和螢幕尺寸下view的適配問題,另外也簡化了旋轉時view的位置的定義,原來在底部之上10像素置中的view,不論在旋轉螢幕或是更換裝置的時候,始終還在底部之上10像素置中的位置,不會發生變化。總之,使用約束條件來描述布局,view的frame會依據這些約束來進行計算.
以上部分內容摘自 : AutoLayout(自動布局)入門
下面說一下我個人對Auto Layout的見解:
1.當你對一個ViewA使用Auto Layout的時候,系統將會只使用Auto Layout中的條件來限制ViewA,而你原先對這個ViewA做的傳統的設定frame或者大小都會立即無效
2.Auto Layout更接近於我們的自然語言,即它是一個更接近我們實際需求的工具
3.Auto Layout是基於約束的,一般來說,一個View至少需要4個約束才能確定其位置和大小
下面我們用Auto Layout解決上述問題:
約束使用方法;
1.拖進去一個button,在button上按住ctrl鍵+左鍵,拖動到主View上,
或者是在左邊的Document Outline中
2.鬆手,會出現彈出框:
其中Leading Space to Container Margin為距離其左邊界
Trailing Space to Container Margin為距離其右邊界
Top Space to Top Layout Guide為距離其上邊界
Buttom Space to Buttom Layout Guide為距離其下邊界
設定其大小可以這樣:
在其Width中填入約束寬度,在Height中填入約束高度
3.添加好約束後,改變其各個約束的值:
好了,我們設定此button的約束分別為距離螢幕左邊界為20pt,右邊界為20pt,距上為30pt,高度自身為20pt(從這裡可以看出約束確實與實際問題非常相符),來看看效果:
iphone6橫豎屏:
ipad air橫豎屏:
非常好,跟預想一致,而且也非常的簡單
那麼,約束的原理是什麼呢?
其實,約束差不多是下面一個公式組成的:
A = B * m + c
或者
viewA.attribute = viewB.attributs*multiplier + constant
我們看圖中的距左的約束:
右邊的四個框分別對應A = B * m + c運算式的 A , B , c , m
換算成語言即為,button的左邊是螢幕左邊界乘以一在加上20pt,跟我們的問題也是一樣的
所以,加入我們想讓button的頂部部是主View底部的四分之三的話,可以設定button的頂部與主View底部的約束中的的Multiplier為0.75,Constant為0
注意,這時候必須要先將button距離頂部的那個距離給刪除掉,否則會出現約束過多導致混亂的情況
方法:
添加一個Buttom Space to Buttom Layout Guide的限制,將Multiplier為0.75,Constant為0,記得一定要將First Item 改為Button.Top,因為預設是Button.Bottom,:
運行即可查看效果,沒有任何問題
通過布局檔案使用Auto Layout就先說到這,其實這裡面還有很多學問,以後有時間在寫出來。
只使用布局檔案來使用Auto Layout還是有一些不足,因為都是寫死的,有的時候還是不能滿足需求,我們還可以在代碼中動態改變布局檔案中約束的Constant,或者動態添加約束,這些將在下一篇中寫出
著作權聲明:本文為博主原創文章,未經博主允許不得轉載。
IOS介面適配二: Auto Layout的使用(上)