1. 程式人生 > >iOS 自動佈局框架

iOS 自動佈局框架

目前iOS開發中大多數頁面都已經開始使用Interface Builder的方式進行UI開發了,但是在一些變化比較複雜的頁面,還是需要通過程式碼來進行UI開發的。而且有很多比較老的專案,本身就還在採用純程式碼的方式進行開發。

而現在iPhoneiPad螢幕尺寸越來越多,雖然開發者只需要根據螢幕點進行開發,而不需要基於畫素點進行UI開發。但如果在專案中根據不同螢幕尺寸進行各種判斷,寫死座標的話,這樣開發起來是很吃力的。

所以一般用純程式碼開發UI的話,一般都是配合一些自動化佈局的框架進行螢幕適配。蘋果為我們提供的適配框架有:VFLUIViewAutoresizingAuto LayoutSize Classes

等。

其中Auto Layout是使用頻率最高的佈局框架,但是其也有弊端。就是在使用UILayoutConstraint的時候,會發現程式碼量很多,而且大多都是重複性的程式碼,以至於好多人都不想用這個框架。

後來Github上的出現了基於UILayoutConstraint封裝的第三方佈局框架MasonryMasonry使用起來非常方便,本篇文章就詳細講一下Masonry的使用。

佔位圖

Masonry介紹

這篇文章只是簡單介紹Masonry,以及Masonry的使用,並且會舉一些例子出來。但並不會涉及到Masonry的內部實現,以後會專門寫篇文章來介紹其內部實現原理,包括順便講一下鏈式語法。

什麼是Masonry

Masonry是一個對系統NSLayoutConstraint進行封裝的第三方自動佈局框架,採用鏈式程式設計的方式提供給開發者API。系統AutoLayout支援的操作,Masonry都支援,相比系統API功能來說,Masonry是有過之而無不及。

Masonry採取了鏈式程式設計的方式,程式碼理解起來非常清晰易懂,而且寫完之後程式碼量看起來非常少。之前用NSLayoutConstraint寫很多程式碼才能實現的佈局,用Masonry最少一行程式碼就可以搞定。下面看到Masonry的程式碼就會發現,太簡單易懂了。

Masonry是同時支援MaciOS兩個平臺的,在這兩個平臺上都可以使用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進行約束時,有一些是需要注意的。

  1. 在使用Masonry新增約束之前,需要在addSubview之後才能使用,否則會導致崩潰。
  2. 在新增約束時初學者經常會出現一些錯誤,約束出現問題的原因一般就是兩種:約束衝突和缺少約束。對於這兩種問題,可以通過除錯和log排查。
  3. 之前使用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為了讓程式碼使用和閱讀更容易理解,所以直接通過點語法就可以呼叫,還添加了andwith兩個方法。這兩個方法內部實際上什麼都沒幹,只是在內部將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自動佈局和UITableViewCell

1、自動佈局 一個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視覺化