iOS 自動佈局框架
目前iOS
開發中大多數頁面都已經開始使用Interface Builder
的方式進行UI
開發了,但是在一些變化比較複雜的頁面,還是需要通過程式碼來進行UI
開發的。而且有很多比較老的專案,本身就還在採用純程式碼的方式進行開發。
而現在iPhone
和iPad
螢幕尺寸越來越多,雖然開發者只需要根據螢幕點進行開發,而不需要基於畫素點進行UI
開發。但如果在專案中根據不同螢幕尺寸進行各種判斷,寫死座標的話,這樣開發起來是很吃力的。
所以一般用純程式碼開發UI
的話,一般都是配合一些自動化佈局的框架進行螢幕適配。蘋果為我們提供的適配框架有:VFL
、UIViewAutoresizing
、Auto Layout
、Size Classes
其中Auto Layout
是使用頻率最高的佈局框架,但是其也有弊端。就是在使用UILayoutConstraint
的時候,會發現程式碼量很多,而且大多都是重複性的程式碼,以至於好多人都不想用這個框架。
後來Github
上的出現了基於UILayoutConstraint
封裝的第三方佈局框架Masonry
,Masonry
使用起來非常方便,本篇文章就詳細講一下Masonry
的使用。
Masonry介紹
這篇文章只是簡單介紹Masonry
,以及Masonry
的使用,並且會舉一些例子出來。但並不會涉及到Masonry
的內部實現,以後會專門寫篇文章來介紹其內部實現原理,包括順便講一下鏈式語法。
什麼是Masonry
Masonry
是一個對系統NSLayoutConstraint
進行封裝的第三方自動佈局框架,採用鏈式程式設計的方式提供給開發者API
。系統AutoLayout
支援的操作,Masonry
都支援,相比系統API
功能來說,Masonry
是有過之而無不及。
Masonry
採取了鏈式程式設計的方式,程式碼理解起來非常清晰易懂,而且寫完之後程式碼量看起來非常少。之前用NSLayoutConstraint
寫很多程式碼才能實現的佈局,用Masonry
最少一行程式碼就可以搞定。下面看到Masonry
的程式碼就會發現,太簡單易懂了。
Masonry
是同時支援Mac
和iOS
兩個平臺的,在這兩個平臺上都可以使用Masonry
MASUtilities.h
檔案中,看到下面的定義,這就是Masonry
通過巨集定義的方式,區分兩個平臺獨有的一些關鍵字。
123456789 | #if TARGET_OS_IPHONE #import #define MAS_VIEW UIView#define MASEdgeInsets UIEdgeInsets#elif TARGET_OS_MAC#import #define MAS_VIEW NSView#define MASEdgeInsets NSEdgeInsets#endif |
整合方式
Masonry
支援CocoaPods
,可以直接通過podfile
檔案進行整合,需要在CocoaPods
中新增下面程式碼:
1 | pod'Masonry' |
Masonry學習建議
在UI
開發中,純程式碼和Interface Builder
我都是用過的,在開發過程中也積累了一些經驗。對於初學者學習純程式碼AutoLayout
,我建議還是先學會Interface Builder
方式的AutoLayout
,領悟蘋果對自動佈局的規則和思想,然後再把這套思想巢狀在純程式碼上。這樣學習起來更好入手,也可以避免踩好多坑。
在專案中設定的AutoLayout
約束,起到對檢視佈局的標記作用。設定好約束之後,程式執行過程中建立檢視時,會根據設定好的約束計算frame
,並渲染到檢視上。
所以在純程式碼情況下,檢視設定的約束是否正確,要以執行之後顯示的結果和列印的log
為準。
Masonry中的坑
在使用Masonry
進行約束時,有一些是需要注意的。
- 在使用
Masonry
新增約束之前,需要在addSubview
之後才能使用,否則會導致崩潰。 - 在新增約束時初學者經常會出現一些錯誤,約束出現問題的原因一般就是兩種:約束衝突和缺少約束。對於這兩種問題,可以通過除錯和
log
排查。 - 之前使用
Interface Builder
新增約束,如果約束有錯誤直接就可以看出來,並且會以紅色或者黃色警告體現出來。而Masonry
則不會直觀的體現出來,而是以執行過程中崩潰或者列印異常log
體現,所以這也是手寫程式碼進行AutoLayout
的一個缺點。
這個問題只能通過多敲程式碼,積攢純程式碼進行AutoLayout
的經驗,慢慢就用起來越來越得心應手了。
Masonry基礎使用
Masonry基礎API
123456789 | mas_makeConstraints()新增約束mas_remakeConstraints()移除之前的約束,重新新增新的約束mas_updateConstraints()更新約束equalTo()引數是物件型別,一般是檢視物件或者mas_width這樣的座標系物件mas_equalTo()和上面功能相同,引數可以傳遞基礎資料型別物件,可以理解為比上面的API更強大width()用來表示寬度,例如代表view的寬度mas_width()用來獲取寬度的值。和上面的區別在於,一個代表某個座標系物件,一個用來獲取座標系物件的值 |
Auto Boxing
上面例如equalTo
或者width
這樣的,有時候需要涉及到使用mas_
字首,這在開發中需要注意作區分。
如果在當前類引入#import "Masonry.h"
之前,用下面兩種巨集定義宣告一下,就不需要區分mas_
字首。
1234 | // 定義這個常量,就可以不用在開發過程中使用"mas_"字首。#define MAS_SHORTHAND// 定義這個常量,就可以讓Masonry幫我們自動把基礎資料型別的資料,自動裝箱為物件型別。#define MAS_SHORTHAND_GLOBALS |
修飾語句
Masonry
為了讓程式碼使用和閱讀更容易理解,所以直接通過點語法就可以呼叫,還添加了and
和with
兩個方法。這兩個方法內部實際上什麼都沒幹,只是在內部將self
直接返回,功能就是為了更加方便閱讀,對程式碼執行沒有實際作用。
例如下面的例子:
1 | make.top.and.bottom.equalTo(self.containerView).with.offset(padding); |
其內部程式碼實現,實際上就是直接將self
返回。
123 | -(MASConstraint *)with{returnself;} |
更新約束和佈局
關於更新約束佈局相關的API
,主要用以下四個API
:
1234 | -(void)updateConstraintsIfNeeded呼叫此方法,如果有標記為需要重新佈局的約束,則立即進行重新佈局,內部會呼叫updateConstraints方法-(void)updateConstraints重寫此方法,內部實現自定義佈局過程-(BOOL)needsUpdateConstraints當前是否需要重新佈局,內部會判斷當前有沒有被標記的約束-(void)setNeedsUpdateConstraints標記需要進行重新佈局 |
關於UIView
重新佈局相關的API
,主要用以下三個API
:
123 | -(void)setNeedsLayout標記為需要重新佈局-(void)layoutIfNeeded檢視當前檢視是否被標記需要重新佈局,有則在內部呼叫layoutSubviews方法進行重新佈局-(void)layoutSubviews重寫當前方法,在內部完成重新佈局操作 |
Masonry示例程式碼
123 | Masonry本質上就是對系統AutoLayout進行的封裝,包括裡面很多的API,都是對系統API進行了一次二次包裝。typedefNS_OPTIONS(NSInteger,MASAttribute){MASAttributeLeft=1 |
常用方法
設定內邊距
12345678910111213 | /** 設定yellow檢視和self.view等大,並且有10的內邊距。 注意根據UIView的座標系,下面right和bottom進行了取反。所以不能寫成下面這樣,否則right、bottom這兩個方向會出現問題。 make.edges.equalTo(self.view).with.offset(10); 除了下面例子中的offset()方法,還有針對不同座標系的centerOffset()、sizeOffset()、valueOffset()之類的方法。 */[self.yellowView mas_makeConstraints:^(MASConstraintMaker *make){make.left.equalTo(self.view).with.offset(10);make.top.equalTo(self.view).with.offset(10);make.right.equalTo(self.view).with.offset(-10);make.bottom.equalTo(self.view).with.offset(-10);}]; |
通過insets簡化設定內邊距的方式
12345 | // 下面的方法和上面例子等價,區別在於使用insets()方法。[self.blueView mas_makeConstraints:^(MASConstraintMaker *make){// 下、右不需要寫負號,insets方法中已經為我們做了取反的操作了。make.edges.equalTo(self.view).with.insets(UIEdgeInsetsMake(10,10,10,10));}]; |
更新約束
1234567891011121314 | // 設定greenView的center和size,這樣就可以達到簡單進行約束的目的[self.greenView mas_makeConstraints:^(MASConstraintMaker *make){make.center.equalTo(self.view);// 這裡通過mas_equalTo給size設定了基礎資料型別的引數,引數為CGSize的結構體make.size.mas_equalTo(CGSizeMake(300,300));}];// 為了更清楚的看出約束變化的效果,在顯示兩秒後更新約束。dispatch_after(dispatch_time(DISPATCH_TIME_NOW,(int64_t)(2.f*NSEC_PER_SEC)),dispatch_get_main_queue(),^{[self.greenView mas_updateConstraints:^(MASConstraintMaker *make){make.centerX.equalTo(self.view).offset(100);make.size.mas_equalTo(CGSizeMake(100,100));}];}); |
大於等於和小於等於某個值的約束
123456789 | [self.textLabel mas_makeConstraints:^(MASConstraintMaker *make){make.center.equalTo(self.view);// 設定寬度小於等於200make.width.lessThanOrEqualTo(@200);// 設定高度大於等於10make.height.greaterThanOrEqualTo(@(10));}];self.textLabel.text=@"這是測試的字串。能看到1、2、3個步驟,第一步當然是上傳照片了,要上傳正面近照哦。上傳後,網站會自動識別你的面部,如果覺得識別的不準,你還可以手動修改一下。左邊可以看到16項修改引數,最上面是整體修改,你也可以根據自己的意願單獨修改某項,將滑鼠放到選項上面,右邊的預覽圖會顯示相應的位置。"; |
textLabel
只需要設定一個屬性即可
1 | self.textLabel.numberOfLines=0; |
使用基礎資料型別當做引數
123456789101112 | /** 如果想使用基礎資料型別當做引數,Masonry為我們提供了"mas_xx"格式的巨集定義。 這些巨集定義會將傳入的基礎資料型別轉換為NSNumber型別,這個過程叫做封箱(Auto Boxing)。 "mas_xx"開頭的巨集定義,內部都是通過MASBoxValue()函式實現的。 這樣的巨集定義主要有四個,分別是mas_equalTo()、mas_offset()和大於等於、小於等於四個。 */[self.redView mas_makeConstraints:^(MASConstraintMaker *make){make.center.equalTo(self.view);make.width.mas_equalTo(100);make.height.mas_equalTo(100);}]; |
設定約束優先順序
1234567891011 | /** Masonry為我們提供了三個預設的方法,priorityLow()、priorityMedium()、priorityHigh(),這三個方法內部對應著不同的預設優先順序。相關推薦iOS 自動佈局框架目前iOS開發中大多數頁面都已經開始使用Interface Builder的方式進行UI開發了,但是在一些變化比較複雜的頁面,還是需要通過程式碼來進行UI開發的。而且有很多比較老的專案,本身就還在採用純程式碼的方式進行開發。 而現在iPhone和iPad螢幕尺寸越來越多,雖然開 iOS自動佈局框架-Masonry詳解目前iOS開發中大多數頁面都已經開始使用Interface Builder的方式進行UI開發了,但是在一些變化比較複雜的頁面,還是需要通過程式碼來進行UI開發的。而且有很多比較老的專案,本身就還在採用純程式碼的方式進行開發。 而現在iPhone和iPad螢幕 ios自動佈局的坑和與之有關的特殊坑前行文 autoLayout自動佈局在ios開發中有其不可比擬的優勢,簡化的程式碼,讓後期維護變得更簡單。這裡不做autoLayout與autoResize的優勢分析,但是在開發過程中如果不注意就會遇到autoLayout意想不到的坑,下面稍微總結一下, Masonry與iOS自動佈局開源專案Masonry旨在讓自動佈局(Auto Layout)的程式碼更簡潔、可讀性更強。 Masonry ,“一個輕量級的佈局框架,採用更優雅的語法封裝自動佈局”,不需要使用XIB和Storyboard。它的創造者Jonas Budelmann 論證 了儘管自動佈局很強大,但它很快就變得冗長而不可讀 IOS 自動佈局篇 swift這是一系列文章,都讀一下,會更好的理解 通用的Storyboard 通用的stroyboard檔案是通向自適應佈局光明大道的第一步。在一個storyboard檔案中適配iPad和iPhone的佈局在iOS8中已不再是夢想。我們不必再為不同尺寸的Apple移動裝置建立 iOS 自動佈局 兩個UILabel 迷思這幾天寫介面需要自動處理文字的寬度,如下: 付款方式、結賬日、是否需要回單,作為一列的titleLabel,需要自動拉伸,很容易: 自動佈局時,設定寬度>=80 或某固定高度即可。 但是當它右邊緊連一個label2時,設定label2上下左右邊距後,發現lab 關於iOS自動佈局這裡做一個通過程式碼實現自動佈局的Demo,通過IB來做的就不講了,網上相關的資料很多,這裡給出一個寫的不錯的連結,有興趣的同學自己看吧. 要談自動佈局,那基本的檢視是第一步,做了一個這樣的ViewController < iOS自動佈局autolayout(2)n part 1 of this Auto Layout tutorial you saw that the old “struts-and-springs” model for making user interfaces cannot easily solve al iOS自動佈局實現Cell和Tableview高度自適應(SDAutoLayout)SDAutoLayout 一行程式碼搞定自動佈局!致力於做最簡單易用的Autolayout庫。The most easy way for autolayout. ☆新增:cell高度自適應 + label文字自適應☆ >>>> iOS適配,iOS自動佈局的幾種高階用法(autoresizing,Masonry)熟悉iOS開發的人,可能都知道,iOS6出來以後,autolayout自動佈局就出現了,但是剛開始大家都不怎麼用,直到iPhone 5s、iPhone6出來後,螢幕變得越來越多樣,單純用if來判斷尺寸已完全不能滿足了,自動佈局才逐漸走程序序猿的程式設計程式碼中。Autolayout自動佈局為什麼能被大家所常用 iOS自動佈局和UITableViewCell1、自動佈局 一個UI控制元件使用自動佈局可以只設置上邊距(Top space)、下邊距(Bottom speace)、左邊距(Leading Space)、右邊距(Trailing space); 對齊一般是要同時選中兩個控制元件(commond+滑鼠) 【iOS開發】---- iOS自動佈局(一)問題 你想將一個UI 元件放置到螢幕的中央。換句話說,你想你想將一個檢視放置到其父檢視的中央位置,使用限制條件。 方案 建立兩個限制條件:一個是將目標檢視的center.x 位置排列在其父檢視的center.x 位置,並且另外一個是將目標檢視的center.y 位置排列在其父檢視的center.y 位置 【iOS開發】---- iOS自動佈局(二)- (NSArray *) emailTextFieldConstraints { NSMutableArray *result = [[NSMutableArray alloc] init]; NSDictionary *viewsDictionary = NSDictionaryOfVar iOS自動布局框架-Masonry詳解asc github上 區分 block line 優先級 關鍵字 二次 con 目前iOS開發中大多數頁面都已經開始使用Interface Builder的方式進行UI開發了,但是在一些變化比較復雜的頁面,還是需要通過代碼來進行UI開發的。而且有很多比較老的項目,本身就還 iOS仿QQ側滑選單、登入按鈕動畫、仿鬥魚直播APP、城市選擇器、自動佈局等原始碼iOS精選原始碼 QQ側滑選單,右滑選單,QQ展開選單,QQ好友分組 image 登入按鈕 image 3分鐘快捷建立高效能輪播圖 ScrollView巢狀ScrolloView(UITableView 、UICollectionView)解決方案 iOS頭條新聞App、自動佈局、省市區聯動、登入按鈕動畫、Alert彈框效果等原始碼iOS精選原始碼 LEEAlert -- 優雅的Alert ActionSheet 登入按鈕 省市區三級聯動 JHViewCorner - 一行程式碼搞定圓角 JHFrameLayout - 一行程式碼實現自動佈局 MVVM+Masonry+UI iOS Xib自動佈局(轉)使用Xib可以實現控制元件的螢幕適配,但是並不是十全十美。因為我們使用Xib新增約束的時候,比如說距離左邊多少距離,這是設定的一個確定的阿拉伯數字,是絕對的,並不是設定的一個比例,在不同的機型上面,裝置的尺寸寬高不一定,Xib以絕對的阿拉伯數字新增約束並不能做到完美的螢幕適配 ios ——SDAutolayout自動佈局下的cell自定義想要實現 這種樣式的cell ,即與邊界有一定距離, 然後又需要cell的高度可以根據標題自適應,所以選擇了sdautolayout自動佈局框架。 生成一個繼承自UITableViewCell的類,首先定義一個白色的背景bgview,然後依次定義四個label,糧給U IOS UIScrollView的自動佈局寫在開始的話:如果感覺博文解決了你的問題,想轉載本文,請尊重勞動成果,註明轉載來源,謝謝! 這兩天剛研究完成IOS的自動佈局,然後想在UIScrollView裡面也設定自動佈局,完成上下滑動。剛開始感覺UIScrollView的自動佈局也跟其他的一樣簡單,但只有經過嘗試才知 iOS 10 Auto Layout介面自動佈局系列3-使用原生NSLayoutConstraint添加布局約束本系列的第一篇文章介紹了自動佈局的基本原理,第二篇文章通過一個簡單的例子演示瞭如何使用Xcode的Interface Builder(簡稱IB)以視覺化方式新增約束。本篇為該系列的第三篇文章,主要介紹如何通過寫程式碼來添加布局約束。 說句題外話,通過IB視覺化 |