本文章轉自http://www.reibang.com/p/428783e1e47e贡定,學習使用
1. 概念
iOS通過純代碼進行UI開發(fā)的話怎顾,屏幕適配有時會比較麻煩盐类,所以一般都會使用 自動化布局框架 進行屏幕適配工作恤浪,其中 Masonry 是一種非常流行的第三方布局框架。
2. 基礎知識
(1) 設置約束方法
// 添加約束
- (NSArray *)mas_makeConstraints:(void(NS_NOESCAPE ^)(MASConstraintMaker *make))block;
// 更新約束揩晴,更新修改的約束筐钟,在原有的約束基礎上更新同類約束,其他約束不變
- (NSArray *)mas_updateConstraints:(void(NS_NOESCAPE ^)(MASConstraintMaker *make))block;
// 移除約束疹鳄,并重新添加約束
- (NSArray *)mas_remakeConstraints:(void(NS_NOESCAPE ^)(MASConstraintMaker *make))block;
綜述:
make
用第一次添加的拧略, update
用最新的, remake
不但用最新的瘪弓,同時還會把原有的統(tǒng)統(tǒng)刪除垫蛆,不管是不是同類約束
注意:
- 使用 Masonry 添加約束之前,需要在
addSubview
之后 才能生效。
(2) 相關屬性
@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; // 文本基線
@property (nonatomic, strong, readonly) MASConstraint *edges; // 內邊距
@property (nonatomic, strong, readonly) MASConstraint *size; // 尺寸
@property (nonatomic, strong, readonly) MASConstraint *center; // 中點
(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
:支持類型轉換川无,支持復雜類型,是對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
文件中即可:
// 添加這個宏惑芭,就不用帶mas_前綴
#define MAS SHORTHAND
// 添加這個宏,equalTo就等價于mas_equalTo
#define MAS SHORTHAND GLOBALS
// 此頭文件一定要放在上面兩個宏的后面才可生效
#import "Masonry.h"
(4) 約束優(yōu)先級
// 設置優(yōu)先級
- (MASConstraint * (^)(MASLayoutPriority priority))priority;
// 優(yōu)先級低
- (MASConstraint * (^)(void))priorityLow;
// 優(yōu)先級中
- (MASConstraint * (^)(void))priorityMedium;
// 優(yōu)先級高
- (MASConstraint * (^)(void))priorityHigh;
(5) 約束比例
// 約束值為約束對象的乘因數(shù) 即 倍數(shù)
- (MASConstraint * (^)(CGFloat multiplier))multipliedBy;
// 表示約束值為約束對象的除因數(shù) 即 比例
- (MASConstraint * (^)(CGFloat divider))dividedBy;
3. 使用技巧
(1) 多行顯示
// 首先addSubview
[self.view addSubview:self.textLabel];
// 設置約束
[self.textLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.center.equalTo(self.view);
// 設置寬度 小于等于300
make.width.mas_lessThanOrEqualTo(300);
// 設置高度 大于等于20
make.height.mas_greaterThanOrEqualTo(20);
}];
self.textLabel.text = @"蒹葭蒼蒼继找,白露為霜遂跟。所謂伊人,在水一方婴渡。溯洄從之幻锁,道阻且長。溯游從之边臼,宛在水中央哄尔。蒹葭萋萋,白露未晞柠并。所謂伊人岭接,在水之湄声怔。溯洄從之忙芒,道阻且躋。溯游從之昧廷,宛在水中坻粘拾。";
// 1. 設置多行顯示
self.textLabel.numberOfLines = 0;
// 2. 設置最大寬度
self.textLabel.preferredMaxLayoutWidth = 300;
// 3. 設置UILayout優(yōu)先級及軸向
[self.textLabel setContentCompressionResistancePriority:UILayoutPriorityRequired forAxis:UILayoutConstraintAxisHorizontal];
(2) 設置內邊距
[self.view addSubview:self.firstView];
[self.firstView mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.left.equalTo(self.view).offset(10);
// 注意根據(jù)UIView的坐標系窄锅,right和bottom進行取反。
make.bottom.right.mas_equalTo(-10);
}];
[self.firstView mas_makeConstraints:^(MASConstraintMaker *make) {
// insets方法自動做出取反操作
make.edges.equalTo(self.view).insets(UIEdgeInsetsMake(10, 10, 10, 10));
}];
(3) 多個控件等間隔排序
/**
* 多個控件固定間隔的等間隔排列缰雇,變化的是控件的長度或者寬度值
*
* @param axisType 軸線方向
* @param fixedSpacing 間隔大小
* @param leadSpacing 頭部間隔
* @param tailSpacing 尾部間隔
*/
- (void)mas_distributeViewsAlongAxis:(MASAxisType)axisType
withFixedSpacing:(CGFloat)fixedSpacing
leadSpacing:(CGFloat)leadSpacing
tailSpacing:(CGFloat)tailSpacing;
/**
* 多個固定大小的控件的等間隔排列,變化的是間隔的空隙
*
* @param axisType 軸線方向
* @param fixedItemLength 每個控件的固定長度或者寬度值
* @param leadSpacing 頭部間隔
* @param tailSpacing 尾部間隔
*/
- (void)mas_distributeViewsAlongAxis:(MASAxisType)axisType
withFixedItemLength:(CGFloat)fixedItemLength
leadSpacing:(CGFloat)leadSpacing
tailSpacing:(CGFloat)tailSpacing;
(4) 更新約束之后動畫效果
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
[self.view addSubview:self.firstView];
// 設置約束
[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));
}];
// 告訴約束需要更新入偷,但不會立即更新,
//[self.firstView.superview setNeedsUpdateConstraints];
[self.view setNeedsUpdateConstraints];
// 檢測當前視圖及其子視圖是否需要更新約束
[self.view updateConstraintsIfNeeded];
[UIView animateWithDuration:0.4 animations:^{
// 立即更新約束
[self.view layoutIfNeeded];
}];
}
(5) For循環(huán)創(chuàng)建多個控件
// 創(chuàng)建一個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動態(tài)Cell高度
原理:
- 對tableView設置預估高度械哟;
- 對自定義Cell里面的控件盯串,要設置cell里最上方控件與cell.contentView上方的距離,最下方控件與cell.contentView下方的距離戒良。
// 1. 對tableView設置預估高度体捏;
- (UITableView *)tableView {
if (!_tableView) {
_tableView = [[UITableView alloc] initWithFrame:CGRectZero style:UITableViewStylePlain];
_tableView.delegate = self;
_tableView.dataSource = self;
// 設置預估高度
_tableView.estimatedRowHeight = 50;
}
return _tableView;
}
// 2. 對自定義Cell里面的控件,要設置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) {
// 設置邊距相對于scrollView的約束
make.edges.equalTo(scrollView);
// 設置寬度
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) {
// 設置contentView的底部約束等于最后一個視圖底部約束
make.bottom.equalTo(lastView.mas_bottom);
}];
}