你好,歡迎來到IOS教程網

 Ios教程網 >> IOS編程開發 >> IOS開發基礎 >> 如何設計一個自動布局庫:以SDAutoLayout為例

如何設計一個自動布局庫:以SDAutoLayout為例

編輯:IOS開發基礎

1.jpg

       前言:SDAutoLayout 在發布之後受到了眾多iOS開發者的青睐和支持,不到半年時間內在GitHub上已經獲得2000+star,同時被眾多公司和個人開發者作為開發首選自動布局庫。現在,以SDAutoLayout為例簡單介紹一下如何設計一個自動布局庫。


       所謂自動布局,其實就是將手動布局的計算過程抽象出一套算法,然後利用約束模型收集view的寬高左右等各個維度對應的數據,最後在恰當的時機根據約束計算出view的frame。


       了解了這個基本原理之後,我們就可以動手設計一個自動布局庫了。在設計自動布局庫的過程中,我們主要需要解決以下幾個問題:


       1.何時進行自動布局相關運算?

       2.如何實現自動布局算法?

       3.如何設計約束模型管理機制?

       4.如何設計一套簡潔的連式語法API?(此步非必須項,僅供有興趣者參考,以SDAutoLayout為例)

       5.如何實現自動計算cell高度?


  1. 何時進行自動布局相關運算?

      

       首先,什麼時候進行自動布局相關運算才最合適呢?我們知道,當一個view的frame發生改變或者由於其他情況需要調整子view就會觸發 layoutSubvies方法,在手動布局時我們經常通過重寫這個方法來實現對子view的調整。但是我們要設計自動布局庫時,顯然不應該強行重寫 view的layoutSubvies方法,這樣就會破壞了開發者對view的自主監聽和掌控,因此,layoutSubvies方法執行完畢之後才是我 們進行自動布局相關運算的最佳時機。好的,那麼究竟如何監控這個“最佳時機”的到來呢?此時我想熟悉OC運行時的同學已經想到了,沒錯,就是利用OC的黑 魔法“Method Swizzling”即可完美解決,代碼如下(源碼地址 ):


blob.png

交換layoutSubvies方法

blob.png


2.如何實現自動布局算法?


       當解決了自動布局運算時機的問題之後,我們面臨的下一個問題就是如何設計自動布局算法,這也是整個自動布局庫最核心的部分。

       在講這個布局算法之前,有必要先說一下我總結出的一個自動布局算法要素:先計算絕對屬性,後計算相對屬性。

       那麼,何為“相對屬性”?相對屬性就是需要參照於其他物體才有意義的屬性。比如我們會說“河南在河北的南面”,那麼這個“南”就是一個相對屬性,有了河北 作為參照,這個“南”才是有意義的,如果你只說“河南在南面”,那麼這個“南”就是沒有意義的。在自動布局中,一個view的x、y、centerX、 centerY、left、right等屬性就屬於這種相對屬性。

       對比“相對屬性”,“絕對屬性”就很好理解了,所謂“絕對屬性”就是不依賴於參照物改變而改變的屬性。比如我會說“iPhone6 是4.7英寸屏幕”,那麼這個“4.7英寸”就是絕對屬性,他不會因為和其他參照物比較而改變。在自動布局中,一個view的width、height屬 性就是這種絕對屬性。

       另外,在針對每個“相對屬性”計算過程中,“寬高校驗”是非常有必要的,如果寬高是不准確的,那麼計算出來的right、bottom、centerX、centerY等屬性值也肯定是不准確的。示例代碼如下(源碼地址):


blob.png

自動布局

blob.png

right自動布局方法實現

3.如何設計約束模型管理機制?


       然後,我們還要設計一下自動布局約束管理機制,也就是說,每個view的約束該交由誰來管理呢?是view自己?還是view的superView呢?結 合剛剛對問題一的分析,既然是父view在調用layoutSubvies方法之後再進行自動布局計算,那麼讓父view來管理所有子view的約束就再 合理不過了。在SDAutoLayout中,每個view都有一個autoLayoutModelsArray數組來管理子view的約束,子view在 調用sd_layout方法時候會初始化一個約束模型並添加到其父view的autoLayoutModelsArray數組中,這就是為什麼在使用 SDAutoLayout過程中要先將子view添加到父view然後再做布局設置的原因了。示例代碼如下(源碼地址):


blob.png

初始化約束模型

4.如何設計一套簡潔的連式語法API?


       鏈式語法以其簡潔明了的優點受到了眾多開發者的推崇,在SDAutoLayout庫中,約束模型將各種布局數據設置的操作封裝進一個個block中,每次 置一個維度的約束時實際上是調用了這個維度對應的block,把相關參數以(參數1,參數2)的形式傳遞給block進行相關設置,然後block每次把 約束模型自身作為返回結果傳遞下去,這樣就可以再次用"."來調用其他維度約束對應的block。示例代碼如下(源碼地址):


blob.png

設置約束

blob.png

每個維度約束對應的block

blob.png

內部實現

5.如何實現自動計算cell高度?


        SDAutoLayout為開發者提供了簡潔高效的cell高度自動計算方法,使用者只需調用一行代碼“[yourCell setupAutoHeightWithBottomView:bottomView bottomMargin:bottomMargin];”即可輕松實現cell高度自動計。

        為了實現此功能,SDAutoLayout庫在內部建立一個和你的cell一樣的模型,然後把你傳遞過來的model數據賦值給模型cell,設置完成後 調用“[self.modelCell.contentView layoutSubviews]”方法來計算cell的真實高度然後返回給你的tableView,同時還會建立cell高度緩存庫以供 tableView滾動時直接返回cell高度而不必再次計算,如果有需要,你也可以開啟cell的Frame緩存機制,這樣就會在你的cell出現的時 候直接給cell內部控件設置frame而不必時時計算調整,從而大大增加了滾動流暢度。示例代碼如下(源碼地址):


blob.png

開啟cell的frame緩存

blob.png

返回cell高度

blob.png

返回並緩存cell高度


       好了,今天先簡單介紹到這裡,後期還會針對以上提到的五點內容進行詳細深入的介紹,如有好的意見和建議歡迎到SDAutoLayout的GitHub地址https://github.com/gsdios/SDAutoLayout issue我,Thanks!



SDAutoLayout的GitHub地址:https://github.com/gsdios/SDAutoLayout

SDAutoLayout使用者開發的部分app截圖http://www.jianshu.com/p/9bc04d3effb8

自動布局QQ交流群:497140713(1群)   519489682(已滿)

自動布局視頻教程:

SDAutoLayout 基礎版視頻教程:http://www.letv.com/ptv/vplay/24038772.html

SDAutoLayout 進階版視頻教程:http://www.letv.com/ptv/vplay/24381390.html

SDAutoLayout 原理簡介視頻教程:http://www.iqiyi.com/w_19rt0tec4p.html


  1. 上一頁:
  2. 下一頁:
蘋果刷機越獄教程| IOS教程問題解答| IOS技巧綜合| IOS7技巧| IOS8教程
Copyright © Ios教程網 All Rights Reserved