在平時開發過程中,用的最多的布局方式當然就是蘋果自帶的autolayout,但是使用的過程中也發現autolayout自身也有很多的問題。在我們的專案中,由於展現邏輯比較靈活,視覺每期的變化比較大,在使用過程中,很大一部分時間都在調整視覺中,所以想引入乙個更簡單的布局方式,這就是大名鼎鼎的flex,也叫箱型布局。
首先來看看我們在autolayout中遇到的幾個問題
autolayout自身的api簡直***,所以大家使用過程中往往會引入第三方庫(masonry, purelayout)。masonry看上去更加直觀,但是不太符合oc的編碼習慣,purelayout更符合oc的規範,使用起來也稍複雜點。兩者都有很多的使用者。雖然第三方庫簡化了api,但並沒有簡化場景。
另乙個autolayout令人詬病的問題,就是當檢視增加的時候,計算複雜度成倍上公升。autolayout依靠解線性方程組,所以越多的檢視效能下降非常大。
在使用場景上,舉幾個例子。
|---- view1 ----|
|---- view2 ----|
|---- view3 ----|
如果要排上圖3個view的時候,autolayout必須指定相互間的依賴。
如果僅僅如此還好解決,那麼現在告訴你,view1可能是個1行或者2行
的label,那麼如何平均分配之間的大小和間隔呢?
如果這樣還是容易解決,那麼再告訴你,view2可能是個沒有內容的檢視
,當沒有檢視的時候1和3之間要保持之前的間距,這時候,不可能簡單的解決了,必須修改依賴,一種方式是刪除所有的autolayout,重新布局一遍,另外一種是儲存autolayout例項,修改單個屬性。無論如何,都不能避免修改依賴。
如果說到這裡你都覺得輕鬆解決,那麼下面這種呢
| |---- view1 ----| | |
| image |---- view2 ----| action1 | action1 |
| |---- view3 ----| | |
這是標準的tableviewcell樣式,但是如果說view和action都是動態的,可能會被隱藏,但隱藏的時候不能空著一塊,垂直的需要居中,水平的需要拉伸。這時候就徹底的蛋疼了,恰好我們的專案中就有很多類似的場景,由此我們很多時間都浪費在調整ui上,又容易漏掉場景導致一些視覺bug。
在一次次的ui修改中,我終於受不了了
在視覺排版這個從印刷術發明就存在的問題,到現在計算機領域,最成熟最靠譜的當然是web技術,從網際網路出現,到現在的響應式介面,web經歷了歷史的歷練,從而產生了一套穩定靠譜的布局方式,而最新的就是不久前被加入標準的flex布局(也可以稱為box布局)。
關於布局使用,有很多有名的介紹文章,我作為乙個半吊子人士,就不做詳細介紹了。簡單來說,就是把每個檢視都看作乙個箱子,擁有內邊距外邊距,然後根據一定順序排布下去,相互間不會產生依賴,當某個檢視的屬性display: none
,自動忽略該檢視。
比autolayout好的地方
首先,flex計算簡單,不會因為檢視的增加效能急劇下降。
同時也可以方便的解決上述的幾種場景,可以動態的根據檢視來排版,而不需要相對的去設定,同時拉伸和擠壓也很好控制(flex-grow, flex-shrink)。
總的來說,使用簡單,學習成本低,效能也很不錯,相容性也高,這也是很多人為什麼會嘲笑蘋果自己搞了一套複雜無比的布局系統。
缺陷flex布局最大的缺陷就是檢視層級的增加,每個箱子都是乙個檢視,看web的**可以發現無數的div
,單純的為了實現一套布局。不過對於移動端來說,乙個檢視不會擁有太多的元素,可以說這個問題沒有那麼的嚴重。
我也在考慮是否可以建立一層virtual view,可以用來代替view作為箱型容器,或者把布局系統移除view作為容器這一web上的邏輯,分離布局和view。無論怎麼樣這兩種方案都會增加複雜度。
同時,由於原生並不提供flex支援,所以需要自己引入flex庫,並且需要在layoutsubview
或者viewdidlayoutsubview
中,手動觸發計算。關於這個問題,可能自己建立系列flex根控制項比較好。
目前使用flex的專案,或者類似的功能
現在最有名的方案是facebook的yoga,遺憾的是ios端的yogakit正處於開發階段,可能不是那麼的穩定
正在使用yoga的開源專案也有很多,有名的有asyncdisplaykit
,react native
,weex
。所以從目前使用場景來看是沒有什麼問題的。
比較相似的功能其實早有方案,比如android的linearlayout和ios的uistackview,可以說這兩者都是閹割版的flex
yogakit
我們來看下yogakit的一些api。不要問我為什麼是swift,老外現在都在玩swift。
root.configurelayout
如果是swift,將會非常簡單,列舉的一半都被省略了,但是oc可能會稍微麻煩一點。api也是幾乎參考的masonry,重要的是,再也不會出現依賴了!!!感覺棒棒的。
同時yoga不是完全的實現了flex的功能,他是為移動端、客戶端專門定製的布局系統,所以也有部分flex沒有的功能,也有部分flex屬性沒有效果。
同時yoga非常的精簡,核心**只有3000多行的c語言,引入成本也非常的低,所以決定在下一期實戰型的使用下,來解決一直遺留的問題。
更多的考慮
在專案的過程中,作為程式設計師,都希望**能夠復用,提高穩定性。然而現實是殘酷的,其他人並不會替你思考這些問題,所以就有很多場景,明明看著一模一樣,但是某幾個字型就是不一樣,大小就是差那麼幾個畫素。那麼要處理這種問題,一般有兩種方案。
1,繼承,基類寫基本成員,子類來寫布局和屬性。這樣會導致很多子類,不熟悉的人會很疑惑這些東西都在**用的。
2,增加style屬性,使用style來重寫布局和屬性,這樣可能會隨著型別的增多switch-case也增加。
同樣,這裡web也給了我們乙個很好的思路。內容-樣式分離,我們可以做一套類似於css的系統,使用class來設定布局樣式,這樣布局樣式也可以復用了!
當然這個思路有部分人已經做好了開源庫,css樣式直接應用到控制項。但是感覺沒有那麼完美,所以以後可以考慮下如何更好的把樣式布局給統一到外部。
原文:flex箱型布局在移動端的應用
移動端布局 flex布局
flex布局原理flex direction 預設主軸x軸水平向右 y軸垂直向下 屬性值描述row 預設從左到右 row reverse 從右到左 column 從上到下 column reverse 從下到上 justify content 屬性值描述 flex start 預設從頭部開始如果主軸...
Flex移動端布局
目前使用flex布局典型的 有天貓和網易新聞。首先,利用flex的專案不需要對viewport進行縮放,直接 簡單回顧一下flex的屬性 一 設定在容器上的屬性 1 flex direction 屬性決定主軸的方向 即專案的排列方向 2 flex wrap 預設顯示在一條軸線上,如果排不下如何換行。...
flex移動端 布局
在移動端中,一般用flex布局來解決當螢幕適應時出現布局錯亂的現象 步驟 1,在開始階段先開啟flex布局,就是在父盒子上display flex 開啟flex布局 而且flex都是對父元素操作來影響子元素的,這裡的子元素是一級子元素,只能影響一級子元素,而且是 所有的一級子元素,其中有幾個重要且常...