在iOS開發(fā)中珠移,使用可視化編程能夠簡單快速的拖拽出令人滿意的UI。但是末融,除了簡單的拖拽之外钧惧,還有一項工作對于可視化編程來講必不可少,那就是AutoLayout自適應(yīng)布局勾习。因為浓瞪,沒有進(jìn)行AutoLayout的UI將無法適應(yīng)屏幕大小不同的機(jī)型。本文主要基于Xcode 7.2.1總結(jié)一下個人在可視化編程中進(jìn)行AutoLayout的幾點經(jīng)驗语卤,大神請繞過追逮。
一、關(guān)于約束
在可視化編程中進(jìn)行AutoLayout的方法就是添加約束粹舵。通過添加合適的約束钮孵,使控件能夠按照預(yù)期的位置和大小顯示在屏幕大小不同的機(jī)型上,也就實現(xiàn)了AutoLayout自適應(yīng)布局眼滤。
1巴席、添加約束
學(xué)習(xí)過可視化編程的小猿們應(yīng)該都知道添加約束的幾種主要方法:
方法一:使用 Interface Builder 界面右下角的 Stack 、Align 诅需、Pin 漾唉、Resolve Auto Layout Issues 四個約束操作按鈕。
方法二:在 Interface Builder 界面上堰塌,按住 control 鍵赵刑,從控件開始拖動鼠標(biāo)到參考控件上,松開鼠標(biāo)就會彈出約束選擇窗口(如圖 1-1)场刑。
圖 1-1
方法三:在 Interface Builder 界面左側(cè)的 Document Outline 窗口中般此,按住 control 鍵,從控件開始拖動鼠標(biāo)到參考控件上,松開鼠標(biāo)就會彈出約束選擇窗口(如圖 1-2)铐懊。
圖 1-2
2邀桑、約束分類
從上面的截圖中我們可以發(fā)現(xiàn),約束大致上可以分為三類:
2.1? 距離約束
距離約束主要用于限定控件相對于參考控件的距離關(guān)系科乎。相對于不同的參考控件壁畸,距離約束的具體名稱會有一些區(qū)別,但作用效果基本相同茅茂。例如:
相對于根 View 的距離約束為:Leading Space to Container Margin 捏萍、Trailing Space to Container Margin 、Vertical Spacing to Top Layout Guide 空闲、Vertical Spacing to Bottom Layout Guide 照弥。
相對于非根 View 的父 View 的距離約束為:Top Space to Container 、Leading Space to Container 进副、Bottom Space to Container 、Trailing Space to Container 悔常。
相對于無包含關(guān)系的其它控件的距離約束為:Horizontal Spacing 影斑、Vertical Spacing 。
2.2? 對齊約束
對齊約束主要用于限定控件相對于參考控件的距離關(guān)系机打。同樣矫户,相對于不同的參考控件,對齊約束的具體名稱也會有一些區(qū)別残邀。例如:
相對于跟 View 或父 View 的對齊約束為:Center Horizontally in Container 皆辽、Center Vertically in Container 。
相對于無包含關(guān)系的其它控件的對齊約束為:Center Horizontally 芥挣、Center Vertically 驱闷。
2.3? 寬高約束
寬高約束主要用于限定控件相對于參考控件的寬高關(guān)系,包括:Equal Widths 空免、Equal Heights 空另、Aspect Ratio 。
二蹋砚、窺探精髓
上面講述了關(guān)于約束的基本內(nèi)容扼菠,但具有可視化編程經(jīng)驗的小猿們都清楚,只知道這些基本內(nèi)容還遠(yuǎn)不足以添加出能夠滿足各種 AutoLayout 需求的約束坝咐。所以說循榆,接下來我們就深入其中,窺探精髓墨坚。
在 Interface Builder 界面中選中某個控件秧饮,我們就可以在 右側(cè) Utilities 窗口 —> Size 選項卡 —> Constraints 選項 下查看已經(jīng)添加的約束(如圖 2-1),并可以點擊 Edit 或者雙擊進(jìn)入約束詳情對這些約束進(jìn)行編輯。
圖 2-1
或者我們可以直接在 Interface Builder 界面選中控件上的具體約束浦楣,在 右側(cè) Utilities 窗口 —> Size 選項卡 下就會顯示約束詳情(如圖 2-2)袖肥,可直接進(jìn)行編輯。
圖 2-2
約束詳情中都包括哪些內(nèi)容呢振劳?下面我們就來詳細(xì)了解一下椎组。
在圖 2-2 中我們可以看到,約束詳情的最上面是約束的名稱历恐,也就是圖中的 Center X Alignment Constraint 寸癌;最下面是一個 Placeholder 選項,內(nèi)容是 Remove at build time 弱贼,從字面意思就可以知道蒸苇,如果選擇了這個選項,編譯時將會移除這個約束吮旅,所以說一般情況下我們是不會勾選這個選項的溪烤;詳情中剩余的內(nèi)容也就是需要重點講述的內(nèi)容,其實這些內(nèi)容都可以用 NSLayoutConstraint 的屬性進(jìn)行描述:
First Item:(id firstItem 屬性).(NSLayoutAttribute firstAttribute 屬性)庇勃,其中的 firstAttribute 屬性是可選的檬嘀。
Relation:NSLayoutRelation relation 屬性,有三個選項可供選擇:Less Than or Equal(<=)责嚷、Equal(=)以及 Greater Than or Equal(>=)鸳兽,默認(rèn)是 Equal(=)。
Second Item:(id secondItem 屬性).(NSLayoutAttribute secondAttribute 屬性)罕拂,其中的 secondAttribute 屬性是可選的揍异。
Constant:CGFloat constant 屬性,常數(shù)爆班,可以手動輸入衷掷,用以對約束進(jìn)行調(diào)整。
Priority:UILayoutPriority priority 屬性柿菩,優(yōu)先級棍鳖,默認(rèn)值為1000,可以手動輸入碗旅,一般不做修改渡处。
Multiplier:CGFloat multiplier 屬性,系數(shù)祟辟,可以手動輸入医瘫,用以對約束進(jìn)行調(diào)整。
Identifier:NSString *identifier 屬性旧困,約束標(biāo)識醇份。
這些內(nèi)容遵循一個公式來限定約束:
First Item =(<=稼锅、>=) Multiplier × Second Item + Constant
這個公式就是約束的精髓,也就是可視化編程 AutoLayout 的精髓僚纷。公式中 First Item 的 firstAttribute 屬性和 Second Item 的 secondAttribute 屬性是可選的矩距,Multiplier 系數(shù)和 Constant 常數(shù)可以手動輸入,所以說我們可以通過編輯約束來隨心所欲的修改約束怖竭,進(jìn)而限定控件的位置和大小锥债,實現(xiàn)可視化編程中的各種 AutoLayout 需求。
三痊臭、特殊需求
1哮肚、Label 的高度自適應(yīng)
Label 的高度自適應(yīng)非常簡單。具有可視化編程經(jīng)驗的小猿們都知道广匙,給 Label 加約束時不添加寬高約束也不會報錯允趟,因為系統(tǒng)默認(rèn) Label 的 numberOfLines = 1,height = 20.5鸦致,寬度根據(jù)文字長短自適應(yīng)潮剪。但有些時候,我們需要使用 Label 顯示一段很長的文本分唾,就需要進(jìn)行高度自適應(yīng):添加約束限定 Label 寬度鲁纠,在 右側(cè) Utilities 窗口 —> Attributes 選項卡 —> Label 選項 下將 Lines 設(shè)置為0。
2鳍寂、ScrollView 的 AutoLayout
曾經(jīng)嘗試過在可視化編程中對 ScrollView 進(jìn)行 AutoLayout 的小猿們都知道,如果我們以 ScrollView 作為參考控件給其上的控件添加寬高約束情龄,系統(tǒng)就會報錯迄汛。怎么辦呢?曾經(jīng)有朋友告訴過我一個使用三方解決的方法骤视,具體是什么三方我不記得了鞍爱,因為我基本不會用這種方法。
那么我是怎么解決的呢专酗?其實只要清楚問題的根源睹逃,我們就可以很簡單的解決它。
我們使用代碼創(chuàng)建 ScrollView 的時候祷肯,都必須要給定它的 contentSize 屬性沉填,但是我們在可視化編程時并沒有對這一屬性進(jìn)行設(shè)置。所以佑笋,當(dāng)我們以 ScrollView 作為參考控件給其上的控件添加寬高約束時翼闹,系統(tǒng)自然就會報錯。解決問題辦法也就是在給 ScrollView 上的控件添加寬高約束時以除 ScrollView 以外的其它控件作為參考控件蒋纬。
考慮到我們可能會在 ScrollView 上添加很多個控件猎荠,最好的作法就是先在 ScrollView 上添加一個空白 View 作為 contentView 坚弱,添加好約束后將需要添加的控件添加到 contentView 上,這時就可以按照正常添加約束的方法給這些控件添加約束了关摇。下面的動畫演示的是在 ScrollView 上添加一個與根 View 等寬荒叶、高度為根 View 高度2倍的 contentView ,并添加約束的過程:
圖 3-1
3输虱、TableViewCell 的高度自適應(yīng)
在實際開發(fā)中可能經(jīng)常會遇到 Cell 的高度要根據(jù)顯示的文字的多少進(jìn)行調(diào)整的需求些楣,這種情況下,如果我們通過可視化編程來定制 customCell 悼瓮,又該怎樣添加約束來使 customCell 的高度能夠自適應(yīng)呢戈毒?
首先,我們要給 customCell 中顯示文字的 Label 添加約束:
第一步:限定 Label 的寬度横堡,但不要限定 Label 的高度埋市,因為 Label 高度自適應(yīng)之后 customCell 才能高度自適應(yīng);
第二步:通過 Leading Space 或 Trailing Space 或 Center.X 限定 Label 在水平方向上的位置命贴;
第三步:限定 Label 的 Top Space 和 Bottom Space 兩個距離約束道宅;
第四步:在 右側(cè) Utilities 窗口 —> Attributes 選項卡 —> Label 選項 下將 Lines 設(shè)置為0。
然后胸蛛,我們要在代碼中設(shè)置 TableView 的 estimatedRowHeight 和 rowHeight 屬性:
self.tableView.estimatedRowHeight = 30 ;? ? // 設(shè)置 customCell 的估計高度
self.tableView.rowHeight = UITableViewAutomaticDimension;? ? // 設(shè)置 customCell 自適應(yīng)高度
這樣污茵,我們就實現(xiàn)了 TableViewCell 的高度自適應(yīng)。
四葬项、實例演示
接下來根據(jù)實際開發(fā)中的一個 AutoLayout 需求泞当,來給大家做一個小小的演示。之前一個朋友給提了一個 AutoLayout 的需求民珍,具體的 UI 效果如圖 4-1襟士,要求三個 ImageView 等寬等高,之間的兩個間隔和屏幕邊緣的兩個間隔寬度相等嚷量。朋友告訴我說他是在四個間隔區(qū)域使用了四個空白的占位 View 陋桂,然后再添加如下約束:
1、添加距離約束:限定兩邊的空白 View 與屏幕邊緣的距離為0蝶溶,限定四個占位 View 與三個 ImageView 兩兩之間的距離為0嗜历;
2、添加對齊約束:限定四個占位 View 和三個 ImageView 相對于根 View 豎直居中抖所;
3梨州、添加寬高約束:限定四個占位 View 和三個 ImageView 的高度均為 0.2 × 屏幕高度,限定四個占位 View 的寬度均為 0.07 × 屏幕寬度田轧,限定三個 ImageView 的寬度均為 0.24 × 屏幕寬度摊唇。
圖 4-1
如果試著把這些約束添加一遍,就會發(fā)現(xiàn)這種方法非常麻煩涯鲁,還容易出錯巷查。但是有序,這篇文章讀到這里,我們已經(jīng)完全沒必要再使用這種浪費空白占位 View 又非常麻煩的方法了岛请。我們完全可以只對三個 ImageView 添加約束來實現(xiàn)圖 4-1中的 UI 效果旭寿。計算 Multiplier 系數(shù)的過程請自行腦補(bǔ),下面只演示添加約束的過程:
圖 4-2