本文章轉(zhuǎn)自http://www.itdecent.cn/p/428783e1e47e,學(xué)習(xí)使用
1. 概念
iOS通過純代碼進(jìn)行UI開發(fā)的話,屏幕適配有時(shí)會(huì)比較麻煩,所以一般都會(huì)使用 自動(dòng)化布局框架 進(jìn)行屏幕適配工作,其中 Masonry 是一種非常流行的第三方布局框架。
2. 基礎(chǔ)知識(shí)
(1) 設(shè)置約束方法
// 添加約束
- (NSArray *)mas_makeConstraints:(void(NS_NOESCAPE ^)(MASConstraintMaker *make))block;
// 更新約束,更新修改的約束,在原有的約束基礎(chǔ)上更新同類約束,其他約束不變
- (NSArray *)mas_updateConstraints:(void(NS_NOESCAPE ^)(MASConstraintMaker *make))block;
// 移除約束,并重新添加約束
- (NSArray *)mas_remakeConstraints:(void(NS_NOESCAPE ^)(MASConstraintMaker *make))block;
綜述:
make用第一次添加的, update用最新的, remake不但用最新的,同時(shí)還會(huì)把原有的統(tǒng)統(tǒng)刪除,不管是不是同類約束
注意:
- 使用 Masonry 添加約束之前,需要在
addSubview之后 才能生效。
(2) 相關(guān)屬性
@property (nonatomic, strong, readonly) MASConstraint *left; // 左側(cè)
@property (nonatomic, strong, readonly) MASConstraint *top; // 上側(cè)
@property (nonatomic, strong, readonly) MASConstraint *right; // 右側(cè)
@property (nonatomic, strong, readonly) MASConstraint *bottom; // 下冊(cè)
@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; // 橫向中點(diǎn)
@property (nonatomic, strong, readonly) MASConstraint *centerY; // 縱向中點(diǎn)
@property (nonatomic, strong, readonly) MASConstraint *baseline; // 文本基線
@property (nonatomic, strong, readonly) MASConstraint *edges; // 內(nèi)邊距
@property (nonatomic, strong, readonly) MASConstraint *size; // 尺寸
@property (nonatomic, strong, readonly) MASConstraint *center; // 中點(diǎn)
(3) 常用方法
// 等于
- (MASConstraint * (^)(id attr))equalTo;
- (MASConstraint * (^)(id attr))mas_equalTo;
// 大于等于
- (MASConstraint * (^)(id attr))greaterThanOrEqualTo;
- (MASConstraint * (^)(id attr))mas_greaterThanOrEqualTo;
// 小于等于
- (MASConstraint * (^)(id attr))lessThanOrEqualTo;
- (MASConstraint * (^)(id attr))mas_lessThanOrEqualTo;
// 偏移量
- (MASConstraint * (^)(CGFloat offset))offset;
- (MASConstraint * (^)(id offset))mas_offset;
1> 方法區(qū)別
-
equalTo:僅支持基本類型; -
mas_equalTo:支持類型轉(zhuǎn)換,支持復(fù)雜類型,是對(duì)equalTo的封裝;
支持CGSize、CGPoint、NSNumber、UlEdgeinsets。
例如:
make.width.equalTo(@100); 等同于
make.width.mas_equalTo(100);
make.bottom.equalTo(self.view); 等同于
make.bottom.mas_equalTo(self.view.mas_bottom);
2> 簡化方法
想要去掉mas_前綴,只用equalTo,將一下代碼添加到.prefix文件中即可:
// 添加這個(gè)宏,就不用帶mas_前綴
#define MAS SHORTHAND
// 添加這個(gè)宏,equalTo就等價(jià)于mas_equalTo
#define MAS SHORTHAND GLOBALS
// 此頭文件一定要放在上面兩個(gè)宏的后面才可生效
#import "Masonry.h"
(4) 約束優(yōu)先級(jí)
// 設(shè)置優(yōu)先級(jí)
- (MASConstraint * (^)(MASLayoutPriority priority))priority;
// 優(yōu)先級(jí)低
- (MASConstraint * (^)(void))priorityLow;
// 優(yōu)先級(jí)中
- (MASConstraint * (^)(void))priorityMedium;
// 優(yōu)先級(jí)高
- (MASConstraint * (^)(void))priorityHigh;
(5) 約束比例
// 約束值為約束對(duì)象的乘因數(shù) 即 倍數(shù)
- (MASConstraint * (^)(CGFloat multiplier))multipliedBy;
// 表示約束值為約束對(duì)象的除因數(shù) 即 比例
- (MASConstraint * (^)(CGFloat divider))dividedBy;
3. 使用技巧
(1) 多行顯示
// 首先addSubview
[self.view addSubview:self.textLabel];
// 設(shè)置約束
[self.textLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.center.equalTo(self.view);
// 設(shè)置寬度 小于等于300
make.width.mas_lessThanOrEqualTo(300);
// 設(shè)置高度 大于等于20
make.height.mas_greaterThanOrEqualTo(20);
}];
self.textLabel.text = @"蒹葭蒼蒼,白露為霜。所謂伊人,在水一方。溯洄從之,道阻且長。溯游從之,宛在水中央。蒹葭萋萋,白露未晞。所謂伊人,在水之湄。溯洄從之,道阻且躋。溯游從之,宛在水中坻。";
// 1. 設(shè)置多行顯示
self.textLabel.numberOfLines = 0;
// 2. 設(shè)置最大寬度
self.textLabel.preferredMaxLayoutWidth = 300;
// 3. 設(shè)置UILayout優(yōu)先級(jí)及軸向
[self.textLabel setContentCompressionResistancePriority:UILayoutPriorityRequired forAxis:UILayoutConstraintAxisHorizontal];
(2) 設(shè)置內(nèi)邊距
[self.view addSubview:self.firstView];
[self.firstView mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.left.equalTo(self.view).offset(10);
// 注意根據(jù)UIView的坐標(biāo)系,right和bottom進(jìn)行取反。
make.bottom.right.mas_equalTo(-10);
}];
[self.firstView mas_makeConstraints:^(MASConstraintMaker *make) {
// insets方法自動(dòng)做出取反操作
make.edges.equalTo(self.view).insets(UIEdgeInsetsMake(10, 10, 10, 10));
}];
(3) 多個(gè)控件等間隔排序
/**
* 多個(gè)控件固定間隔的等間隔排列,變化的是控件的長度或者寬度值
*
* @param axisType 軸線方向
* @param fixedSpacing 間隔大小
* @param leadSpacing 頭部間隔
* @param tailSpacing 尾部間隔
*/
- (void)mas_distributeViewsAlongAxis:(MASAxisType)axisType
withFixedSpacing:(CGFloat)fixedSpacing
leadSpacing:(CGFloat)leadSpacing
tailSpacing:(CGFloat)tailSpacing;
/**
* 多個(gè)固定大小的控件的等間隔排列,變化的是間隔的空隙
*
* @param axisType 軸線方向
* @param fixedItemLength 每個(gè)控件的固定長度或者寬度值
* @param leadSpacing 頭部間隔
* @param tailSpacing 尾部間隔
*/
- (void)mas_distributeViewsAlongAxis:(MASAxisType)axisType
withFixedItemLength:(CGFloat)fixedItemLength
leadSpacing:(CGFloat)leadSpacing
tailSpacing:(CGFloat)tailSpacing;
(4) 更新約束之后動(dòng)畫效果
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
[self.view addSubview:self.firstView];
// 設(shè)置約束
[self.firstView mas_makeConstraints:^(MASConstraintMaker *make) {
make.center.equalTo(self.view);
make.width.height.mas_equalTo(100);
}];
}
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
// 更新約束
[self.firstView mas_remakeConstraints:^(MASConstraintMaker *make) {
make.edges.equalTo(self.view).insets(UIEdgeInsetsMake(10, 10, 10, 10));
}];
// 告訴約束需要更新,但不會(huì)立即更新,
//[self.firstView.superview setNeedsUpdateConstraints];
[self.view setNeedsUpdateConstraints];
// 檢測當(dāng)前視圖及其子視圖是否需要更新約束
[self.view updateConstraintsIfNeeded];
[UIView animateWithDuration:0.4 animations:^{
// 立即更新約束
[self.view layoutIfNeeded];
}];
}
(5) For循環(huán)創(chuàng)建多個(gè)控件
// 創(chuàng)建一個(gè)View作為容器
UIView *lastView = [[UIView alloc] init];
[self.view addSubview:lastView];
[lastView mas_makeConstraints:^(MASConstraintMaker *make) {
make.edges.equalTo(self.view).insets(UIEdgeInsetsMake(15, 15, 15,15));
}];
for (int i = 0; i < 10; i++) {
// 創(chuàng)建新的view
UIView *view = [[UIView alloc] init];
view.backgroundColor = [self randomColor];
[lastView addSubview:view];
[view mas_makeConstraints:^(MASConstraintMaker *make) {
make.edges.equalTo(lastView).insets(UIEdgeInsetsMake(15, 15, 15,15));
}];
// 將view賦值給lastView
lastView = view;
}
(6) UITableView動(dòng)態(tài)Cell高度
原理:
- 對(duì)tableView設(shè)置預(yù)估高度;
- 對(duì)自定義Cell里面的控件,要設(shè)置cell里最上方控件與cell.contentView上方的距離,最下方控件與cell.contentView下方的距離。
// 1. 對(duì)tableView設(shè)置預(yù)估高度;
- (UITableView *)tableView {
if (!_tableView) {
_tableView = [[UITableView alloc] initWithFrame:CGRectZero style:UITableViewStylePlain];
_tableView.delegate = self;
_tableView.dataSource = self;
// 設(shè)置預(yù)估高度
_tableView.estimatedRowHeight = 50;
}
return _tableView;
}
// 2. 對(duì)自定義Cell里面的控件,要設(shè)置cell里最上方控件與cell.contentView上方的距離,最下方控件與cell.contentView下方的距離。
- (void)settingUI {
[self.contentView addSubview:self.detailLabel];
[self.detailLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.edges.equalTo(self.contentView).insets(UIEdgeInsetsMake(15, 15, 15, 15));
}];
}
(7) scrollView使用約束的問題
原理:給scrollView添加唯一的子視圖contentView,通過拉伸子視圖的size來確定scrollView的contentSize。
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
// 創(chuàng)建scrollView
UIScrollView *scrollView = [[UIScrollView alloc] init];;
scrollView.backgroundColor = [UIColor redColor];
[self.view addSubview:scrollView];
[scrollView mas_makeConstraints:^(MASConstraintMaker *make) {
make.edges.equalTo(self.view);
}];
// 創(chuàng)建contentView,添加到scrollView作為唯一子視圖
UIView *contentView = [[UIView alloc] init];
contentView.backgroundColor = [UIColor whiteColor];
[scrollView addSubview:contentView];
[contentView mas_makeConstraints:^(MASConstraintMaker *make) {
// 設(shè)置邊距相對(duì)于scrollView的約束
make.edges.equalTo(scrollView);
// 設(shè)置寬度
make.width.equalTo(scrollView);
}];
UIView *lastView;
for (NSInteger i = 0; i < 10; i++) {
UIView *view = [UIView new];
view.backgroundColor = [self randomColor];
[contentView addSubview:view];
[view mas_makeConstraints:^(MASConstraintMaker *make) {
if (i == 0) {
make.top.equalTo(contentView);
} else {
make.top.equalTo(lastView.mas_bottom).offset(10);
}
make.left.right.equalTo(contentView);
make.height.mas_equalTo(100);
}];
lastView = view;
}
[contentView mas_makeConstraints:^(MASConstraintMaker *make) {
// 設(shè)置contentView的底部約束等于最后一個(gè)視圖底部約束
make.bottom.equalTo(lastView.mas_bottom);
}];
}