在Xcode中,自動佈局看似是一個很複雜的系統,在真正使用它以前,我也是這麼認爲的,不過事實並不是如此。佈局
咱們知道,一款iOS應用,其主要UI組件是由一個個相對獨立的可視單元構成,這些可視單元有的主要負責向用戶輸出有用的信息,有些則負責信息的輸入(交互),交互的過程當中每每還伴隨有動畫的效果,已達到整個信息傳遞的連貫性以及用戶體驗的細膩感。可視單元,在實際開發中主要是view、button等,那麼這些可視單元的關係由兩個基本的關係構成:兄弟關係和父子關係,整個視圖單元就是一個樹形結構:動畫
對於任何一個UI組件,肯定了它的(相對於父view)位置、大小也就肯定了它在整個UI視圖中的展現效果。ui
Autolayout(以及iOS8中新增的sizeclass)是爲了解決這些UI可視單元或者元素是怎樣佈局、排列的問題。在過去只有iPhone4的時候,咱們能夠在代碼裏將沒一個可視單元的位置寫死,這樣是沒問題的,但隨着iPhone五、6的發佈,屏幕尺寸有了愈來愈多中可能,將來不排除更多尺寸的iPhone發佈出來,這就要求咱們的APP的UI元素具備在屏幕尺寸不一樣的設備上具備必定動態的可調性,已實現較好的UI展現效果。從目前蘋果提供的技術來看,有下、中、上三種實現方法:code
下策是,代碼中判斷當前設備的尺寸,對UI元素進行手工的調整,其缺點是顯而易見的:代碼複雜、容易出錯、且維護難度大、靈活性極差;orm
中策是,經過設置可視單元(UIView UIButton...)的autoresizing屬性,預設當該view所在的環境(父view)發生變化時它的尺寸和位置應該如何調整,該方法能夠在Xcode的interface builder中(storyboard 或者 xib)設置完成,但其只能針對父子關係進行有限的調整,好比左邊距是否固定,尺寸是否可變等,而對於兄弟關係的調整則沒法實現,對於UI比較固定的APP這種調節方式也算基本知足需求;開發
上策就是結合使用autolayout和sizeclass對UI可視單元的父子關係、兄弟關係進行全方位的調整,並且調節精度更高:不只能肯定一個view的位置尺寸的變化依據是什麼,還能對這些依據加以不一樣的優先級,先知足什麼條件,再知足什麼條件,對於重要的位置尺寸能夠優先保證,這樣整個APP就具備極強的動態可調性,知足不一樣設備、不一樣應用場景下的需求。文檔
在目前蘋果手機蘋果尺寸多達四種的狀況下,顯然新的APP必需要採用上策來解決視圖組件的佈局問題。編譯
Autolayout的做用很是明確:幫咱們肯定在不一樣設備、不一樣(父view)環境下,同一個可視單元所應具備合適的位置和尺寸,所以,當一個UIView上所施加的約束可以惟一肯定它的frame(x, y, width, height)的時候咱們的自動佈局的使用纔是正確的。而新手一般犯的兩類錯誤就是約束不足(約束太少)和約束衝突兩種(約束太多)。若是你給出的約束只可以肯定這個view的大小,或者位置或者位置中的某一個項(好比x)的時候,就會出現約束不足的狀況,在xib或者storyboard中,會以黃色的警告出如今左側提示框內;若是你給出的約束推導出了兩個甚至多個互相矛盾的位置尺寸結果的時候,就產生了佈局錯誤,在編譯的時候直接就build不過。class
在iOS8中,新增了Size Classes特性,它是對當前全部iOS設備尺寸的一個抽象,也是該抽象了,想一想如今多少種iOS尺寸的設備吧:iPhone4-5-6-6plus、iPad、iPad mini、iWatch,如何仍是按照之前那針對種特定設備來編寫不一樣的佈局的話,必定是很糟糕的一件事情。用戶體驗
如今有了sizeclass,事情就好辦多了:你不是設備多嗎,那咱們就只把屏幕的寬和高分別分紅三種狀況:(Compact, Regular, Any),也即緊湊、正常和任意。這樣寬和高三三一整合,一共9中狀況。以下圖所示,針對每一種狀況,若是須要的話,咱們能夠單獨在storyboard或xib中設置UIView的自動佈局約束,甚至某一個button是否顯示都是能輕鬆實現。
關於size class的詳細解析,參考蘋果文檔和wwdc2014視:點擊打開連接 (What's New in Interface Builder)。
對Xcode的interface builder比較熟悉的童鞋應該對UIButton的超強定製性映像深入:經過選擇button的不一樣狀態(normal、height、disabled...),咱們能夠單獨設置每一種狀態,button的background image、image、text color等屬性,見下圖:
和設置UIButton的不一樣狀態的不一樣屬性相似,咱們首先選擇一種size class,而後針對該種size class進行自動佈局。下面咱們以一個簡單的佈局場景爲例進行說明:
假設,咱們想實現下面這個效果:橫屏和豎屏頭像和label都能正常的現實,且在「比較恰當」的位置:顯然橫屏的時候,高度處於壓縮的狀態,(height: compact),咱們須要先對正常的佈局以外,還要添加一種(wAny, hCompact)size class的佈局:
首先,咱們對默認的sizeclass進行佈局,肯定頭像和label的位置和尺寸:
設置完(wAny hAny)以後,點擊wAny hAny文字(上圖底部),選擇(wAny hCompact):注意點擊後彈出一個九宮格浮框,拖動鼠標便可選擇響應的size class,注意在右下角(紅色方框表示),還能夠選擇是否install,若是取消勾選,則這個頭像在當前size class下就不會被加載(天然也就不顯示出來)。
在新的size class下咱們開始添加新的佈局,注意,這裏並無覆蓋上一種size class咱們定義好了得佈局,知識針對當前的size class添加新的、獨立的佈局信息,狡兔三窟,Xcode6這下子一口氣給了咱們九個窟窿,爽!
佈局完畢,運行起來,便可達到咱們想要的效果!