如何設計一個自動布局庫

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

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

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

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

????? 2.如何實現(xiàn)自動布局算法?

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

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

????? 5.如何實現(xiàn)自動計算cell高度?

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

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

交換layoutSubvies方法

2.如何實現(xiàn)自動布局算法?

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

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

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

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

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

自動布局
right自動布局方法實現(xiàn)

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

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

初始化約束模型

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

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

設置約束
每個維度約束對應的block
內部實現(xiàn)

5.如何實現(xiàn)自動計算cell高度?

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

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

開啟cell的frame緩存
返回cell高度
返回并緩存cell高度

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



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

SDAutoLayout使用者開發(fā)的部分app截圖http://www.lxweimin.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

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 發(fā)現(xiàn) 關注 消息 iOS 第三方庫、插件、知名博客總結 作者大灰狼的小綿羊哥哥關注 2017.06.26 09:4...
    肇東周閱讀 12,250評論 4 61
  • 2017.02.22 可以練習,每當這個時候,腦袋就犯困,我這腦袋真是神奇呀,一說讓你做事情,你就犯困,你可不要太...
    Carden閱讀 1,378評論 0 1
  • Creating Custom Layouts 為穿戴式設備創(chuàng)建布局和在手機上的操作一樣,不過為了整體平衡和諧感你...
    lucky9322閱讀 495評論 0 3
  • 電面要點 安靜地坐下來,拿著紙筆進行記錄。 用重視、嚴謹?shù)膽B(tài)度來對待電話面試。 接聽電話時要用“你好”等禮貌用語。...
    Hello_Lisa閱讀 214評論 0 0
  • 關注簡書很久了,自己也一直很想提筆寫一些東西,但是由于自己的惰性一直沒能行動。今天想來想去,還是想要動筆寫一些,作...
    行腳人閱讀 285評論 0 1