前言
1 | |
以上是純手寫代碼所經曆的關于頁面布局的三個時期
在iphone1-iphone3gs時代 window的size固定為(320,480) 我們隻需要簡單計算一下相對位置就好了
在iphone4-iphone4s時代 蘋果推出了retina屏 但是給了碼農們非常大的福利:window的size不變
在iphone5-iphone5s時代 window的size變了(320,568) 這時autoresizingMask派上了用場(為啥這時候不用Autolayout? 因為還要支援ios5呗) 簡單的适配一下即可
在iphone6+時代 window的width也發生了變化(相對5和5s的螢幕比例沒有變化) 終于是時候抛棄autoresizingMask改用autolayout了(不用支援ios5了 相對于螢幕适配的多樣性來說autoresizingMask也已經過時了)
那如何快速的上手autolayout呢? 說實話 當年ios6推出的同時新增了autolayout的特性 我看了一下官方文檔和demo 就立馬抛棄到一邊了 因為實在過于的繁瑣和啰嗦(有過經驗的朋友肯定有同感)
直到iPhone6釋出之後 我知道使用autolayout勢在必行了 這時想起了以前在浏覽Github看到過的一個第三方庫Masonry 在花了幾個小時的研究使用後 我就将autolayout掌握了(重點是我并沒有學習任何的官方文檔或者其他的關于autolayout的知識) 這就是我為什麼要寫下這篇文章來推薦它的原因.
介紹
Masonry 源碼:https://github.com/Masonry/Masonry
Masonry是一個輕量級的布局架構 擁有自己的描述文法 采用更優雅的鍊式文法封裝自動布局 簡潔明了 并具有高可讀性 而且同時支援 iOS 和 Max OS X。
我們先來看一段官方的sample code來認識一下Masonry
1 2 3 | |
看到block裡面的那句話: make edges equalTo superview with insets
通過鍊式的自然語言 就把view1給autolayout好了 是不是簡單易懂?
使用
看一下Masonry支援哪一些屬性
1 2 3 4 5 6 7 8 9 10 11 | |
這些屬性與NSLayoutAttrubute的對照表如下
其中leading與left trailing與right 在正常情況下是等價的 但是當一些布局是從右至左時(比如阿拉伯文?沒有類似的經驗) 則會對調 換句話說就是基本可以不理不用 用left和right就好了
在ios8釋出後 又新增了一堆奇奇怪怪的屬性(有興趣的朋友可以去瞅瞅) Masonry暫時還不支援(不過你要支援ios6,ios7 就沒必要去管那麼多了)
在講執行個體之前 先介紹一個MACRO
1 | |
快速的定義一個weakSelf 當然是用于block裡面啦 下面進入正題(為了友善 我們測試的superView都是一個size為(300,300)的UIView)
下面 通過一些簡單的執行個體來簡單介紹如何輕松愉快的使用Masonry:
1. [基礎] 居中顯示一個view
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | |
代碼效果
使用我之間寫的MMPlaceHolder 可以看到superview已經按照我們預期居中并且設定成了适當的大小
那麼先看看這幾行代碼
1 2 3 4 5 6 7 8 9 10 11 12 | |
這裡有兩個問題要分解一下
首先在Masonry中能夠添加autolayout限制有三個函數
1 2 3 4 5 6 7 8 9 | |
其次 equalTo 和 mas_equalTo的差別在哪裡呢? 其實 mas_equalTo是一個MACRO
1 2 3 4 | |
可以看到 mas_equalTo隻是對其參數進行了一個BOX操作(裝箱) MASBoxValue的定義具體可以看看源代碼 太長就不貼出來了
所支援的類型 除了NSNumber支援的那些數值類型之外 就隻支援CGPoint CGSize UIEdgeInsets
介紹完這幾個問題 我們就繼續往下了 PS:剛才定義的sv會成為我們接下來所有sample的superView
2. [初級] 讓一個view略小于其superView(邊距為10)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | |
代碼效果
可以看到 edges 其實就是top,left,bottom,right的一個簡化 分開寫也可以 一句話更省事
那麼為什麼bottom和right裡的offset是負數呢? 因為這裡計算的是絕對的數值 計算的bottom需要小魚sv的底部高度 是以要-10 同理用于right
這裡有意思的地方是and和with 其實這兩個函數什麼事情都沒做
1 2 3 4 5 6 | |
但是用在這種鍊式文法中 就非常的巧妙和易懂 不得不佩服作者的心思(雖然我現在基本都會省略)
3. [初級] 讓兩個高度為150的view垂直居中且等寬且等間隔排列 間隔為10(自動計算其寬度)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | |
代碼效果
這裡我們在兩個子view之間互相設定的限制 可以看到他們的寬度在限制下自動的被計算出來了
4. [中級] 在UIScrollView順序排列一些view并自動計算contentSize
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | |
頭部效果
尾部效果
從scrollView的scrollIndicator可以看出 scrollView的内部已如我們所想排列好了
這裡的關鍵就在于container這個view起到了一個中間層的作用 能夠自動的計算uiscrollView的contentSize
5. [進階] 橫向或者縱向等間隙的排列一組view
很遺憾 autoLayout并沒有直接提供等間隙排列的方法(Masonry的官方demo中也沒有對應的案例) 但是參考案例3 我們可以通過一個小技巧來實作這個目的 為此我寫了一個Category
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 | |
簡單的來測試一下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | |
代碼效果
perfect! 簡潔明了的達到了我們所要的效果
這裡所用的技巧就是 使用空白的占位view來填充我們目标view的旁邊 這點通過圖上的空白标注可以看出來
小結
通過以上5個案例 我覺得已經把Masonry的常用功能介紹得差不多了 如果你覺得意猶未盡呢 請下載下傳官方的demo來學習
總而言之 Masonry是一個非常優秀的autolayout庫 能夠節省大量的開發和學習時間 尤其适合我這種純代碼的iOSer 在iPhone6釋出後引發的适配潮中 Masonry一定可以助你一臂之力 :) 感謝原作 辛苦啦。