iOS Autolayout 介紹

noark9發表於2016-07-09

簡介

曾經 iPhone 和 iPad 的螢幕的邏輯解析度只有唯一的一個大小,所以在 iOS 上開發應用是非常幸福的,我們不需要面對大量的螢幕尺寸和解析度,但是隨著 iPhone5,6,6 plus,iPad Pro 的出現,以及 iOS 上提供的分屏多工的支援,應對不同解析度的佈局在現在 iOS 開發中已經變的非常重要,在 iOS 上常用的佈局方式有下面幾種:

  • 程式碼佈局,在 - layoutSubview 的時候調整每個元素的位置、大小實現 UI 的佈局
  • UIViewAutoresizing 通過設定一系列的開關決定每個 view 在父 view 發生變化時如何處理,這種方式一般會和程式碼佈局的方式相配和完成比較複雜的 UI 佈局
  • Autolayout,也是今天的主角,通過設定元素之間的關係來決定每個 view 的位置

佈局解決的是什麼問題

Autolayout 要解決的問題是佈局的問題,也就是 UI 上面每個元素的位置問題,在使用程式碼佈局的時代我們在 - viewDidLoad 方法中設定每個元素的初始位置,在 - layoutSubviews 方法中,解決父 view 發生變化時介面上各個元素應該如何再次佈局的問題,同時方便我們會配合 UIViewAutoresizing 的開關來簡化部分程式碼。

佈局,要解決的問題就是 UI 上每個元素應該如何放置,他們的大小,以及絕對的位置在哪裡,並且在 UI 發生變化,螢幕發生變化時,應如何應對。不論是通過程式碼佈局,還是通過 Autolayout 佈局,我們要做的都是告訴系統,每個元素在哪裡,以及元素的寬和高。

Autolayout 和程式碼佈局的區別是,Autolayout 通過告訴佈局引擎每個元素之間的相對位置(也就是元素之間的關係)讓佈局引擎推斷出每個元素的絕對位置和元素大小並告訴系統如何顯示,程式碼佈局則是每次直接告訴系統每個元素的絕對位置和大小。

Autolayout 基礎

Interface Builder 上的 Autolayout 工具介紹

下面介紹下在 Xcode 的 Interface Builder 中怎麼做一些基本的佈局操作

Butons

上面截圖是 Interface Builder 介面右下角的四個按鈕,從左到右分別是:

  • Stack:把 View 放到 Stack View 中(Stack View 是 iOS 9 中提供的新東西,這裡暫時先不講)
  • Align:設定 View 和 View 之間如何對齊(左對齊,右對齊)
  • Pin:設定固定 View 的位置
  • Resolve Auto Layout Issues:解決 Autolayout 中佈局出現的問題

接著我們分別看看 Align,Pin,Resolve Auto Layout Issues 三個按鈕分別有些什麼功能吧

Pin Menu 主要是提供功能讓我們去決定每個 View 和其他 View 之間的關係,上下左右之間的絕對距離,寬度和高度

Pin Menu

Align Menu 提供了讓我們決定兩個 View 之間是如何對齊的

Align Menu

這裡要注意的是 Baseline 是文字排版用的,在文字排版時使用 Baseline 對齊,可以讓文字看上去是寫在一行上,具體點這裡->Baseline 是什麼<-

Pin 和 Align 可以針對單個 View 也可以針對多個 View,如果選中了多個 View 並設定距離左邊是4時,那麼所選中的所有 View 到左邊的距離都是4,並且在 Add Counstraint 按鈕上會顯示總共新增了多少個約束。

Resolve Auto Layout Issues 提供了在約束和 Interface Builder 中所顯示的 View 佈局不一致時的一些解決工具

Resolve Auto Layout Issues  Menu

Resolve 工具中,實際上並不實用,畢竟 Interface Builder 也只是 Apple 給的一個介面佈局工具,他並不能得到我們到底在想什麼,所以想要佈局完全按照我們想得方式來工作,建議使用手工新增布局,新增完成後使用 Update Frames 功能,檢視我們的佈局是否和我們想要的一致。

接下來我們來說說 Xcode 介面右邊的 Size Inspector 的功能

在選中一個 View 後,可以看到下面的介面:

Inspector

在選中具體的一個 NSLayoutConstraint 物件(也就是上下文一直說的約束)後,可以看到下面的介面:

Inspector

在 Interface Builder 中出現黃色的警告,表示約束和 View 設計上的位置大小不一致,可以通過檢查相關佈局來發現是否新增的約束有問題,也可以直接使用 Resolve Auto Layout Issues 選單中的 Update Frames 選項來調整 View 的大小,觀察是否和期待一致。

在 Interface Builder 中出現紅色警告的時候,表示存在約束衝突,或是缺少了約束,這兩個問題的真實原因是因為我們提供的約束,無法讓 Interface Builder 根據整個 View Controller 中的所有約束計算得到有問題的 View 的具體位置和大小,這個時候要檢查有問題的 View 或者約束,看是否無法決定 View 的位置或是大小。

對於類似 UILabelUIImageView 等有內容的 View 可以通過設定 Hugging 和 Compression 約束的優先順序來解決某一個方向上如果父 View 不足的情況下,哪些 View 會被壓縮或是不被壓縮的問題。例如下圖的 QQ 聊天介面,聊天內容在很長的時候壓縮了聊天內容的預覽,讓未讀訊息數量能夠完整的顯示。

QQ 聊天介面

下一步做什麼

有了上面的內容,大家基本可以很愉快的在 Interface Builder 上和 Autolayout 玩耍了。

最後注意:Autolayout 沒有魔法,只是幫我們從另一個角度(View 之間的關係)來確定所有 View 的位置,以及適應父 View 的變化,我們要做的是教會 Interface Builder 如何確定每個 View 的絕對位置,Autolayout 有它方便的地方,自然也有不足之處,解決一個問題並不能只過分依賴於某一項特定的技術,而是需要根據實際情況來選擇自己用什麼。

相關文章