iOS Autolayout 介紹 2 Interface Builder 技巧

noark9發表於2016-07-09

start

上一期,介紹了一下 Autolayout 的一些基本做法,以及 iOS 上 AutoLayout 的思想和簡單的原理介紹,有同學給我建議繼續出下一期,這裡,我們就來繼續第二期吧,這一期我們依然停留在 Interface Builder(後面簡寫 IB)上,介紹我在工作中遇到的一些問題,以及依賴 IB 是如何解決的,也不會涉及很多程式碼。

小技巧篇

預覽功能

有時候,我們在拖拽完成佈局後,總想看看效果怎麼辦呢?IB 給我們提供了預覽功能,在 Assistant 編輯器中檔案選擇 preview 就可以看到 IB 佈局後介面的預覽效果了,而且可以新增多個裝置,以及新增橫屏和豎屏的效果。

選擇預覽

等寬 View 怎麼做

有時候會遇到這樣的問題,我的 View 要平均分佈在介面上怎麼辦,比如下圖的介面,我想讓那五個 view 平均的分佈在檢視上怎麼辦呢?

想要等寬

做法其實大家可能已經想到了,那就是設定每個 View 寬度相等,並且間距為0。

等寬

這麼看好像沒啥用啊,除了紅藍紅藍相間以外,那麼在平時使用過程中可以實現下面的佈局效果:

  • 在每個 View 中間放上按鈕,那麼就實現了按鈕平均分佈在介面(比如下面的分享介面)

分享介面

  • 在上圖兩塊藍色 View 放上按鈕,紅色 View 設定透明,那麼就可以實現按鈕在 View 上左右間隔相同的佈局(比如下面多看介面的頂部,雖然他們不一定是這麼實現的,但是這樣可以實現這裡只是舉個例子)

多看介面

高度可以隱藏的 UILabel

其實在沒有內容的情況下 UILabel 的大小會變成0,這是因為,UILabel 是由 Content 決定大小的 View,所以在沒有文字的時候,他的大小就變成0了,可以利用這點來簡單實現佈局時,如果有標題那麼顯示標題,如果沒標題,那麼減少空隙的效果。

沒內容的 UILabel

使用 UIScrollView

好多同學很不喜歡在 IB 裡面用 ScrollView,原因是 SrollView 的大小,和他的 ContentView 的大小,很不好通過 IB 來決定,之後經過一段時間的研究找到了一個前輩通過程式碼新增新的約束來解決的方法->UIScrollView 使用 Autolayout<-看的時候,估計要自帶梯子,回到正題,既然本篇是 IB 技巧,那麼我們就會用最少量的程式碼來解決問題,對於這個問題,經過一段時間的研究後,其實是不需要程式碼的我們來繼續。

ScrollView 的大小是非常容易確定的,但是 ContentView 的大小就不好確定了,所以我們的目標就是在 IB 中確定 ContentView 的大小,這樣就不需要再通過程式碼新增約束來設定 ContentView 的大小了

這裡通過 IB 確定 ContentView 大小的額方法有兩個,第一個是確定 ContentView 裡面所有 View 的大小,來支撐 ContentView 的大小,這個方法應該是很常用了,我們來講第二個方法,直接通過 ScrollView 的大小來確定 ContentView 的大小,這裡假設我們需要 ContentView 和 ScrollView 一樣大,跟著 View 的大小變化而變化,以適應不同的螢幕大小

ScrollView

如圖,一般我們使用 ScrollView 的時候是通過在 ScrollView 內部增加一個 View 並把 View 到 ScrollView 上下左右的距離設定為0,這樣可以讓 View 上下左右緊貼 ScrollView,但是這個時候是不滿足約束條件的,因為這樣是沒辦法確定 ContentView 大小的,那麼接下來怎麼辦呢。

這裡,有一個思維的侷限,總覺的已經讓 ContentView 的上下左右貼著 ScrollView 四邊了,沒辦法繼續做什麼了。

ScrollView

就像上圖操作就可以了,那麼思維侷限在那裡呢,因為我們選中了 ContentView 再按著 Command 或者 Shift 是沒辦法在 IB 中同時選中 View 和他的父 View,或是跨層級選中 View 的,但是在 Outline View 中就可以,這樣其實在 Outline View 中選中了 ContentView 和 ScrollView,使用 Pin 選單(什麼你不知道 Pin 選單,速速戳這裡看上期->戳我戳我<-)中的等寬等高也能實現相同的效果。

前兩天和以前公司小夥伴聊天的時候,他說最後他用只有一行的 TableView 來解決這樣的問題,那麼他只需要決定 Cell 的大小就行了,並且在 iOS 8 以後,可以通過 Cell 的佈局自動獲得 Cell 的大小,這又是另一個解法了,對於 UI 來說只有想不到,沒有做不到。

非 Prototype 型別的 TableView 的作用

如果我們使用 Storyboard 的話,會有另外一個很方便的東西,那就是 Content 型別為 Static Cell 的 TableView,使用 Static Cell 的 TableView,我們可以快速的拖拽一個可以上下滾動的登入介面,設定介面,選項介面等等等等……就像這樣。

TableView

UINibWrapper

在 View 比較複雜,並且部分 View 是可以重用的時候,我們這時候一般會通過把可以重用的 View 建立和事件處理都包裝到子 View 中去建立,程式碼上似乎很容易理解,在 IB 中其實也有一樣的方法,那就是通過指定 View 的 Class 來實現,但是如果我們要用 xib 建立和佈局的 View 的話,方法就是在那個 View 的類中,初始化時載入對應的 xib 檔案,但是每次都要寫這個,好麻煩怎麼辦,有人把這個過程做了一下封裝那就是->UINibWraper<-。

UINibWraper

就像上面,我有一個 View 是很多不同型別的 Cell 都需要的一個操作型別的 View,上面提供了點贊,評論,分享等功能,如果每個 Cell 都畫上去的話,每次改的話,每個 Cell 都需要修改,這就不符合我們懶惰程式設計師的性格了,所以我建立了一個 View 提供這些功能,整合到所有的 Cell 上去。

IB 上的 Object

IB 其實是我們拖拽物件的地方,也就是所有在 IB 上的東西都是物件,那麼這裡我放個平時我們很少用到的一個東西 NSObject,也就是截圖下面這貨:

NSObject

這其實是為 IB 上的物件,新增一個物件用的佔位符,也就是我們可以在我們的 ViewController 中通過 IB 來新增物件,我們可以給 TableView 一個單獨的 Delegate,指定一個特定的物件,通過設定物件的 Class 和 Value 來實現不同的 TableView 在不同的物件中獲取資料,這樣程式碼裡面就不用看到一個 ViewController 中有一堆的 TableView 的 Delegate 方法,讓 ViewController 鍵減肥。

end

對於 UI 來說,只有想不到,沒有做不到,很多方法都是聰明的碼農們想出來的,歡迎大家丟磚。

相關文章