Masonry是對AutoLayout封裝而成的一個(gè)輕量級的布局框架朋凉。其語法優(yōu)雅改览、代碼簡潔低滩,可讀性很高,而且同時(shí)支持iOS和Mac OS X欺抗。
這篇文章主要講解Masonry的用法售碳。
1 安裝Masonry
這里我們使用CocoaPods來安裝Masonry。
首先打開Podfile文件绞呈,添加下面的內(nèi)容:
pod 'Masonry'
如果項(xiàng)目中還沒有Podfile文件贸人,可以在當(dāng)前項(xiàng)目中手動(dòng)創(chuàng)建一個(gè),也可以通過終端定位到項(xiàng)目目錄佃声,使用
pod init
命令創(chuàng)建一個(gè)Podfile文件艺智。
在命令行中輸入pod install
安裝Masonry:
$ pod install
如果出現(xiàn)下面的提示內(nèi)容,則表示Masonry安裝成功:
Analyzing dependencies
Downloading dependencies
Installing Masonry (1.1.0)
Generating Pods project
Integrating client project
[!] Please close any current Xcode sessions and use `MasonryDemo.xcworkspace` for this project from now on.
Sending stats
Pod installation complete! There is 1 dependency from the Podfile and 1 total pod installed.
2 Masonry的使用
首先關(guān)閉之前創(chuàng)建的項(xiàng)目文件圾亏,打開后綴名為xcworkspace的項(xiàng)目十拣。在需要使用Masonry的項(xiàng)目文件中導(dǎo)入Masonry的頭文件。
這里我們創(chuàng)建一個(gè)greenView的子視圖志鹃,并將它添加到self.view上夭问,然后使用Masonry對它進(jìn)行布局,讓其距離父視圖的上下左右邊距均為20:
#import "ViewController.h"
#import "Masonry.h"
@interface ViewController ()
@property (nonatomic, strong) UIView *greenView;
@end
@implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// 添加子視圖
[self.view addSubview:self.greenView];
// 添加布局
[self.greenView mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(self.view).offset(20);
make.right.equalTo(self.view).offset(-20);
make.top.equalTo(self.view).offset(20);
make.bottom.equalTo(self.view).offset(-20);
}];
}
- (UIView *)greenView
{
if (!_greenView) {
_greenView = [[UIView alloc] init];
_greenView.backgroundColor = [UIColor greenColor];
_greenView.layer.borderColor = [UIColor blackColor].CGColor;
_greenView.layer.borderWidth = 2.0;
}
return _greenView;
}
運(yùn)行結(jié)果:
在上面的代碼中曹铃,我們調(diào)用了mas_makeConstraints:
方法給視圖添加布局信息:
[self.greenView mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(self.view).offset(20);
make.left.equalTo(self.view).offset(20);
make.bottom.equalTo(self.view).offset(-20);
make.right.equalTo(self.view).offset(-20);
}];
上面的
left
缰趋、right
、top
陕见、bottom
均是Masonry支持的屬性秘血,分別表示左側(cè)、右側(cè)淳玩、頂部直撤、底部;equalTo
表示約束的關(guān)系蜕着;offset
表示偏移值谋竖,另外還有multipliedBy
表示倍數(shù)值。
上面的代碼也可以寫成:
[self.greenView mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.mas_equalTo(self.view.mas_top).offset(20);
make.left.mas_equalTo(self.view.mas_left).offset(20);
make.bottom.mas_equalTo(self.view.mas_bottom).offset(-20);
make.right.mas_equalTo(self.view.mas_right).offset(-20);
}];
還可以寫成:
[self.greenView mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(@20);
make.left.equalTo(@20);
make.bottom.equalTo(@-20);
make.right.equalTo(@-20);
}];
和:
[self.greenView mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.mas_equalTo(20);
make.left.mas_equalTo(20);
make.bottom.mas_equalTo(-20);
make.right.mas_equalTo(-20);
}];
還可以簡化為:
[self.greenView mas_makeConstraints:^(MASConstraintMaker *make) {
make.edges.equalTo(self.view).with.insets(UIEdgeInsetsMake(20, 20, 20, 20));
}];
和:
[self.greenView mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.left.bottom.and.right.equalTo(self.view).with.insets(UIEdgeInsetsMake(20, 20, 20, 20));
}];
值得一提的是承匣,這里的
and
和with
其實(shí)沒有執(zhí)行任何操作蓖乘,實(shí)際上是可以省略的,但是用在這種鏈?zhǔn)秸Z法中就很巧妙韧骗,增加了語句的可讀性嘉抒,而且特別容易理解。
如果不想使用mas_
前綴袍暴,可以在導(dǎo)入Masonry之前添加下面的宏:
#define MAS_SHORTHAND
例如:
#define MAS_SHORTHAND
#import "ViewController.h"
#import "Masonry.h"
...
[self.greenView makeConstraints:^(MASConstraintMaker *make) {
make.edges.equalTo(self.view).with.insets(UIEdgeInsetsMake(20, 20, 20, 20));
}];
另外些侍,也可以將#define MAS_SHORTHAND
寫在PrefixHeader.pch文件中隶症。
創(chuàng)建PrefixHeader.pch文件
打開File\New\File...,選擇iOS\Other\PCH File岗宣,點(diǎn)擊Next蚂会,修改要保存的文件名稱(這里使用默認(rèn)的),點(diǎn)擊Create即可耗式。
然后在PrefixHeader.pch文件中添加下面的代碼:
#define MAS_SHORTHAND
#import "Masonry.h"
這樣下次再需要使用Masonry的時(shí)候就不需要再導(dǎo)入了胁住,并且也可以省略掉mas_
前綴。
需要注意的是刊咳,PrefixHeader.pch文件需要配置一下才能生效彪见。
配置PrefixHeader.pch文件
選中項(xiàng)目,然后TARGETS\Build Settings娱挨,然后在搜索框中輸入prefix header余指,然后定位到Apple Clang - Language這一欄,將Precompile Prefix Header的值改為YES让蕾,然后在Prefix Header右側(cè)雙擊浪规,在彈出的輸入框中填寫PrefixHeader.pch文件的路徑即可。
這里可以使用
$(SRCROOT)/項(xiàng)目名稱/xxx.pch
這樣的格式來設(shè)置路徑探孝,其中$(SRCROOT)
表示項(xiàng)目所在的目錄。
3 Masonry支持的屬性
前面代碼中我們用到的left
誉裆、right
顿颅、top
、bottom
屬性足丢,其實(shí)Masonry還有很多屬性粱腻。
下面列出的是標(biāo)準(zhǔn)屬性:
@property (nonatomic, strong, readonly) MASConstraint *left;
@property (nonatomic, strong, readonly) MASConstraint *top;
@property (nonatomic, strong, readonly) MASConstraint *right;
@property (nonatomic, strong, readonly) MASConstraint *bottom;
@property (nonatomic, strong, readonly) MASConstraint *leading;
@property (nonatomic, strong, readonly) MASConstraint *trailing;
@property (nonatomic, strong, readonly) MASConstraint *width;
@property (nonatomic, strong, readonly) MASConstraint *height;
@property (nonatomic, strong, readonly) MASConstraint *centerX;
@property (nonatomic, strong, readonly) MASConstraint *centerY;
@property (nonatomic, strong, readonly) MASConstraint *baseline;
除此之外,Masonry還支持margin和safeArea相關(guān)的屬性:
@property (nonatomic, strong, readonly) MASViewAttribute *leftMargin;
@property (nonatomic, strong, readonly) MASViewAttribute *rightMargin;
@property (nonatomic, strong, readonly) MASViewAttribute *topMargin;
@property (nonatomic, strong, readonly) MASViewAttribute *bottomMargin;
@property (nonatomic, strong, readonly) MASViewAttribute *leadingMargin;
@property (nonatomic, strong, readonly) MASViewAttribute *trailingMargin;
@property (nonatomic, strong, readonly) MASViewAttribute *centerXWithinMargins;
@property (nonatomic, strong, readonly) MASViewAttribute *centerYWithinMargins;
@property (nonatomic, strong, readonly) MASViewAttribute *safeAreaLayoutGuideTop;
@property (nonatomic, strong, readonly) MASViewAttribute *safeAreaLayoutGuideBottom;
@property (nonatomic, strong, readonly) MASViewAttribute *safeAreaLayoutGuideLeft;
@property (nonatomic, strong, readonly) MASViewAttribute *safeAreaLayoutGuideRight;
另外斩跌,Masonry還提供了一些方便的方法绍些,可以同時(shí)創(chuàng)建多種約束,它們被稱為MASCompositeConstraints(復(fù)合約束):
@property (nonatomic, strong, readonly) MASConstraint *edges;
@property (nonatomic, strong, readonly) MASConstraint *size;
@property (nonatomic, strong, readonly) MASConstraint *center;
-
edges
make.edges.equalTo(self.view); make.edges.mas_equalTo(UIEdgeInsetsMake(20, 20, 20, 20)); make.edges.equalTo(self.view).insets(UIEdgeInsetsMake(20, 20, 20, 20));
-
size
make.size.greaterThanOrEqualTo(view1); make.size.mas_equalTo(CGSizeMake(300, 200)); make.size.equalTo(self.view).sizeOffset(CGSizeMake(100, -50)); // 表示:view.width = view.superView.width + 100, view.height = view.superView.height - 50
-
center
make.center.equalTo(self.view); make.center.equalTo(@(CGPointMake(100, 200))); make.center.mas_equalTo(CGPointMake(100, 200)); make.center.equalTo(self.view).centerOffset(CGPointMake(-5, 10)); // 表示: view.centerX = view.superView.centerX - 5, view.centerY = view.superView.centerY + 10
4 Masonry中約束的關(guān)系
equalTo
lessThanOrEqualTo
greaterThanOrEqualTo
如果希望greenView的左側(cè)大于或者等于self.view的左側(cè)耀鸦,我們可以在代碼中可以這樣寫:
[self.greenView makeConstraints:^(MASConstraintMaker *make) {
make.left.greaterThanOrEqualTo(self.view);
}];
如果希望greenView的寬度大于等于200柬批,小于等于400,我們可以在代碼中這樣寫:
[self.greenView makeConstraints:^(MASConstraintMaker *make) {
// width >= 200 && width <= 400
make.width.greaterThanOrEqualTo(@200);
make.width.lessThanOrEqualTo(@400);
}];
5 Masonry中約束的優(yōu)先級
-
priority
可以指定一個(gè)確切的優(yōu)先級值袖订,范圍在0 ~ 1000氮帐,值越大優(yōu)先級越高。 -
priorityHigh
相當(dāng)于UILayoutPriorityDefaultHigh
洛姑,優(yōu)先級值為750上沐。 -
priorityMedium
介于高優(yōu)先級和低優(yōu)先級之間,優(yōu)先級值在250 ~ 750之間楞艾。 -
priorityLow
相當(dāng)于UILayoutPriorityDefaultLow
参咙,優(yōu)先級值為250龄广。
優(yōu)先級可以寫在約束鏈的末尾,例如:
make.top.equalTo(self.view).with.priority(800);
make.bottom.equalTo(self.view).priorityMedium();
make.left.equalTo(self.view).priorityLow();
make.right.equalTo(self.view).priorityHigh();
6 創(chuàng)建約束
自動(dòng)布局允許將寬度和高度設(shè)置為常量值蕴侧,例如:
[self.greenView makeConstraints:^(MASConstraintMaker *make) {
make.width.equalTo(@300);
make.height.equalTo(@200);
}];
但是蜀细,自動(dòng)布局不允許將對齊屬性(如left
、right
戈盈、centerY
等)設(shè)置為常量值奠衔。如果為這些屬性傳遞了一個(gè)NSNumber類型的值,Masonry會(huì)將這些變?yōu)橄鄬τ谝晥D的父視圖的約束塘娶,即:
[self.greenView makeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(@10);
}];
相當(dāng)于:
[self.greenView makeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(self.view.mas_left).offset(10);
}];
表示:
view.left = view.superView.left + 10;
除了使用NSNumber類型創(chuàng)建約束以外归斤,還可以使用結(jié)構(gòu)等,示例如下:
make.size.equalTo(@(CGSizeMake(300, 200)));
make.size.mas_equalTo(CGSizeMake(300, 200));
make.edges.mas_equalTo(UIEdgeInsetsMake(20, 20, 20, 20));
make.left.mas_equalTo(self.view).mas_offset(UIEdgeInsetsMake(20, 20, 20, 20));
上面最后一行代碼的效果等同于:
make.left.mas_equalTo(self.view).mas_offset(20);
另外刁岸,還可以使用數(shù)組來傳遞不同類型的值創(chuàng)建約束脏里,例如:
make.height.equalTo(@[view1.mas_height, view2.mas_height]);
make.height.equalTo(@[view1, view2]);
make.left.equalTo(@[view1.right, @100, view2]);
7 使用Masonry更新約束
有時(shí)候我們需要更改現(xiàn)有的約束以設(shè)置動(dòng)畫,或者刪除虹曙、替換約束迫横,在Mansory中,我們可以使用下面的方法來更新約束酝碳。
7.1 將約束的表達(dá)式結(jié)果保存為屬性或變量矾踱,通過使用該約束變量或?qū)傩詠硖砑踊蛘邉h除約束。
例如疏哗,我們可以聲明一個(gè)MASConstraint
類型的屬性:
@property (nonatomic, strong) MASConstraint *topConstraint;
然后定義該屬性:
[self.greenView mas_makeConstraints:^(MASConstraintMaker *make) {
self.topConstraint = make.top.equalTo(self.view).with.offset(20);
}];
后面如果需要重新該約束值呛讲,可以這樣寫:
self.topConstraint.mas_equalTo(20);
另外,還可以根據(jù)需要調(diào)用下面的方法:
[self.topConstraint install]; // 創(chuàng)建NSLayoutConstraint并將其添加到適當(dāng)?shù)囊晥D上返奉。
[self.topConstraint uninstall]; // 刪除之前安裝的NSLayoutConstraint
[self.topConstraint activate]; // 如果操作系統(tǒng)支持NSLayoutConstraint贝搁,可以調(diào)用該方法來激活約束。否則需要調(diào)用install方法芽偏。
[self.topConstraint deactivate]; // 取消激活(使無效)之前安裝/激活的NSLayoutConstraint雷逆。
以之前的greenView為例,我們在self.view上添加一個(gè)點(diǎn)擊手勢污尉,每次點(diǎn)擊的時(shí)候更新greenView的edges約束:
@property (nonatomic, strong) MASConstraint *edgesConstraint;
- (void)viewDidLoad
{
...
// 添加子視圖
[self.view addSubview:self.greenView];
// 給self.view添加點(diǎn)擊手勢
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tap:)];
[self.view addGestureRecognizer:tap];
// 給greenView添加布局
[self.greenView mas_makeConstraints:^(MASConstraintMaker *make) {
self.edgesConstraint = make.edges.equalTo(self.view).with.insets(UIEdgeInsetsMake(20, 20, 20, 20));
}];
}
- (void)tap:(UITapGestureRecognizer *)tap
{
int i = arc4random_uniform(10);
// 更新greenView的布局
self.edgesConstraint.mas_equalTo(UIEdgeInsetsMake(20 * i, 20 * i, 20 * i, 20 * i));
}
效果如下:
另外膀哲,還可以通過將約束存儲(chǔ)在數(shù)組中來引用多個(gè)約束。
7.2 使用mas_updateConstraints
方法更新約束十厢。
如果我們只需要更新約束的常量值等太,我們可以使用mas_updateConstraints
方法來代替mas_makeConstraints
方法。mas_updateConstraints
對于更新一組約束很有用蛮放。
比如我們可以使用下面的代碼替換tap:
方法中的內(nèi)容缩抡,實(shí)現(xiàn)之前的效果:
- (void)tap:(UITapGestureRecognizer *)tap
{
int i = arc4random_uniform(10);
// 使用mas_updateConstraints更新約束
[self.greenView mas_updateConstraints:^(MASConstraintMaker *make) {
make.edges.equalTo(self.view).with.insets(UIEdgeInsetsMake(20 * i, 20 * i, 20 * i, 20 * i));
}];
}
7.3 使用mas_remakeConstraints
方法更新約束。
mas_remakeConstraints
類似于mas_updateConstraints
,但它不是更新常量值瞻想,而是在再次安裝之前刪除所有約束压真。 這樣我們就可以提供不同的約束,而無需保留對要?jiǎng)h除約束的引用蘑险。
- (void)tap:(UITapGestureRecognizer *)tap
{
int i = arc4random_uniform(10);
// 使用remakeConstraints更新約束
[self.greenView mas_remakeConstraints:^(MASConstraintMaker *make) {
make.edges.equalTo(self.view).with.insets(UIEdgeInsetsMake(20 * i, 20 * i, 20 * i, 20 * i));
}];
}
7.4 總結(jié)
-
mas_makeConstraints
只負(fù)責(zé)新增約束滴肿,每次調(diào)用會(huì)創(chuàng)建新的約束,如果對已存在的約束再次創(chuàng)建佃迄,會(huì)提示沖突(此時(shí)會(huì)存在對同一屬性的兩條約束)泼差。 -
mas_updateConstraints
用于更新之前創(chuàng)建的約束,如果對已存在的約束進(jìn)行更新呵俏,沒有任何問題(此時(shí)只存在對同一屬性的最新一條約束)堆缘。 -
mas_remakeConstraints
會(huì)清除之前的所有約束,僅保留最新的約束普碎。
8 使用Masonry定位發(fā)生沖突的約束
使用Masonry可以為視圖和約束創(chuàng)建有意義的名稱吼肥,這樣當(dāng)設(shè)置的約束發(fā)生沖突時(shí),我們可以定位到具體的元素麻车。
例如:如果我們使用下面的代碼為greenView添加布局:
[self.greenView mas_makeConstraints:^(MASConstraintMaker *make) {
make.edges.equalTo(self.view).with.insets(UIEdgeInsetsMake(20, 20, 20, 20));
make.height.lessThanOrEqualTo(@(200));
}];
運(yùn)行的時(shí)候控制臺(tái)會(huì)提示約束沖突:
[LayoutConstraints] Unable to simultaneously satisfy constraints.
......
(
"<MASLayoutConstraint:0x600000f01ce0 UIView:0x7fbdace024b0.top == UIView:0x7fbdace0b630.top + 20>",
"<MASLayoutConstraint:0x600000f01da0 UIView:0x7fbdace024b0.bottom == UIView:0x7fbdace0b630.bottom - 20>",
"<MASLayoutConstraint:0x600000f01e60 UIView:0x7fbdace024b0.height <= 200>",
"<NSLayoutConstraint:0x600000818e10 UIView:0x7fbdace0b630.height == 736>"
)
Will attempt to recover by breaking constraint
<MASLayoutConstraint:0x600000f01e60 UIView:0x7fbdace024b0.height <= 200>
......
面對這樣的輸出缀皱,我們很難找到造成約束沖突的問題。
Masonry為NSLayoutConstraint添加了一個(gè)分類动猬,重寫了- (NSString *)description
方法的默認(rèn)實(shí)現(xiàn)啤斗。這樣我們就可以為視圖和約束提供有意義的名稱,并且還可以輕松選擇由Masonry創(chuàng)建的約束枣察。
更改上面的代碼如下:
self.greenView.mas_key = @"greenView";
self.view.mas_key = @"self.view";
// MASAttachKeys(self.greenView, self.view); // 也可以使用這種寫法自動(dòng)關(guān)聯(lián)一個(gè)key
// 添加布局
[self.greenView mas_makeConstraints:^(MASConstraintMaker *make) {
make.edges.equalTo(self.view).with.insets(UIEdgeInsetsMake(20, 20, 20, 20)).key(@"edgesConstraint");
make.height.lessThanOrEqualTo(@(200)).key(@"heightConstraint");
// make.height.lessThanOrEqualTo(@(200)).key(@1234); // key可以是任意值
}];
這次的運(yùn)行結(jié)果:
[LayoutConstraints] Unable to simultaneously satisfy constraints.
......
(
"<MASLayoutConstraint:edgesConstraint[2] UIView:greenView.top == UIView:self.view.top + 20>",
"<MASLayoutConstraint:edgesConstraint[3] UIView:greenView.bottom == UIView:self.view.bottom - 20>",
"<MASLayoutConstraint:heightConstraint UIView:greenView.height <= 200>",
"<NSLayoutConstraint:0x600002f9f6b0 UIView:self.view.height == 736>"
)
Will attempt to recover by breaking constraint
<MASLayoutConstraint:heightConstraint UIView:greenView.height <= 200>
......
可以很明顯看到greenView設(shè)置的高度約束沖突了争占。
9 使用Masonry布局scrollView
對UIScrollView使用自動(dòng)布局的時(shí)候,經(jīng)常會(huì)遇到很多問題序目,比如布局無效,不能滑動(dòng)等伯襟。主要是因?yàn)閁IScrollView除了有自己的frame之外猿涨,還有一個(gè)contentSize。如果對子視圖進(jìn)行布局時(shí)參考了scrollView姆怪,例如設(shè)置子視圖的leading/trailing/top/bottom屬性等于scrollView的leading/trailing/top/bottom叛赚,這實(shí)際上是子視圖相對于scrollview的contentsize來確定的,而非bounds稽揭。而且由于scrollview的contentSize又是根據(jù)子視圖的位置決定的俺附,這樣就形成了一個(gè)依賴循環(huán)。
為了打破這種循環(huán)依賴溪掀,為ScrollView中的子視圖添加約束的時(shí)候需要注意:
- 子視圖不能依賴任何scrollView有關(guān)的布局事镣,即不能參考scrollView的位置。
- 子視圖除了要確定自己的大小以外揪胃,還需要確定自己與contentSize四周的距離璃哟,以此來確定contentSize氛琢。
比如我們現(xiàn)在有一個(gè)scrollView,將greenView作為子視圖添加到scrollView上随闪,代碼如下:
- (void)viewDidLoad
{
[super viewDidLoad];
[self.view addSubview:self.scrollView];
[self.scrollView addSubview:self.greenView];
// 布局scrollView
[self.scrollView mas_makeConstraints:^(MASConstraintMaker *make) {
make.edges.equalTo(self.view);
}];
// 布局greenView并確定scrollview的contentSize
[self.greenView mas_makeConstraints:^(MASConstraintMaker *make) {
// 1 確定contentSize的大小
make.edges.equalTo(self.scrollView);
// 2 確定greenView的大小
make.height.mas_equalTo(500);
make.width.mas_equalTo(1000);
// make.size.equalTo(self.scrollView).sizeOffset(CGSizeMake(500, -100));
}];
}
上面代碼中我們使用
make.edges.equalTo(self.scrollView);
來確定contentSize的大小阳似,它表示greenView的上下左右距離contentSize的值為0,因此只要greenView的大小確定了铐伴,contentSize也就確定了撮奏。
如果要在scrollView上添加多個(gè)子視圖,可以將多個(gè)子視圖放入一個(gè)containerView中当宴,這樣布局子視圖時(shí)只需要參考containerView就可以了畜吊。
比如現(xiàn)在有一個(gè)scrollView,它里面有多個(gè)子視圖等間隔排列:
我們可以使用下面的代碼來實(shí)現(xiàn):
- (void)viewDidLoad
{
[super viewDidLoad];
[self.view addSubview:self.scrollView];
[self.scrollView addSubview:self.containerView];
[self.scrollView mas_makeConstraints:^(MASConstraintMaker *make) {
make.edges.equalTo(self.view).inset(20);
}];
[self.containerView mas_makeConstraints:^(MASConstraintMaker *make) {
make.edges.equalTo(self.scrollView);
make.height.mas_equalTo(self.scrollView);
}];
// 添加子視圖
int count = 10;
UIView *previousView = nil;
for (int i = 1; i <= count; ++i) {
UIView *subView = [UIView new];
subView.backgroundColor = [UIColor greenColor];
subView.layer.borderColor = [UIColor blackColor].CGColor;
subView.layer.borderWidth = 2.0;
[self.containerView addSubview:subView];
// 布局子視圖
[subView mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.bottom.equalTo(self.containerView);
make.width.mas_equalTo(80);
if (previousView) {
make.left.equalTo(previousView.mas_right).offset(10);
}
else {
make.left.equalTo(self.containerView).offset(10);
}
}];
previousView = subView;
}
// 確定containerView的右邊界
[self.containerView mas_makeConstraints:^(MASConstraintMaker *make) {
make.right.equalTo(previousView);
}];
}
10 注意事項(xiàng)
- 對視圖使用自動(dòng)布局之前即供,需要先將視圖添加到父視圖上定拟。
- 使用Masonry時(shí)注意區(qū)分
mas_equalTo
和equalTo
的區(qū)別:-
mas_equalTo
:- 是對equalTo的封裝,支持NSNumber逗嫡、CGSize青自、CGPoint、UIEdgeInsets驱证;
- mas_equalTo是一個(gè)Macro延窜,比較的是值;
- 一般對于數(shù)值元素使用mas_equalTo抹锄,例如
make.width.mas_equalTo(100);
逆瑞。
-
equalTo
:- 只支持基本類型;
- equalTo比較的是view伙单;
- 對于對象或多個(gè)屬性的處理使用equalTo获高,例如
make.left.and.right.equalTo(self.view);
。
-
- 對視圖使用自動(dòng)布局后吻育,如果嘗試獲取它的frame很可能獲取到的是0念秧。對于這種情況,我們可以在獲取視圖frame之前手動(dòng)調(diào)用
layoutIfNeeded
方法來更新布局布疼。 - Masonry中的block不存在循環(huán)引用的問題摊趾,不必使用weakSelf。雖然block內(nèi)引用了view游两,但block并沒有被view所持有砾层,因此不會(huì)發(fā)生循環(huán)引用。
11 參考資料
Masonry
Masonry介紹與使用實(shí)踐(快速上手Autolayout)
Masonry 簡單使用
iOS開發(fā)之Masonry框架-使用方法須知
ScrollView使用Masonry自動(dòng)布局
史上最簡單的UIScrollView+Autolayout出坑指南
iOS開發(fā)筆記 | 由使用Masonry布局不能立即獲取到frame想到的一些問題
Masonry布局控件frame為0的問題