iOS-Masonry的简单使用

1.Masonry的基本API

mas_makeConstraints()   // 添加约束
mas_remakeConstraints()  //移除之前的约束,重新添加新的约束
mas_updateConstraints()  //更新约束

equalTo()      // 参数是对象类型,一般是视图对象或者mas_width这样的坐标系对象
mas_equalTo()   //和上面功能相同,参数可以传递基础数据类型对象,可以理解为比上面的API更强大
width()         //用来表示宽度,例如代表view的宽度
mas_width()     //用来获取宽度的值。和上面的区别在于,一个代表某个坐标系对象,一个用来获取坐标系对象的值

上面例如equalTo或者width这样的,有时候需要涉及到使用mas_前缀,注意区分。

//控件左边 = 参考控件的右边 + 偏移值(10) (控件在参考控件的右边,距离其5px)
make.left.equalTo(view.superview.mas_right).offset(10);//不填则默认对应left,其他同理

注意:masequalTo 和 equalTo 区别:masequalTo 比equalTo多了类型转换操作,一般来说,大多数时候两个方法都是通用的,但是对于数值元素使用mas_equalTo。对于对象或是多个属性的处理,使用equalTo。特别是多个属性时,必须使用equalTo,例如make.left.and.right.equalTo(self.view);

注意:在循环cell,如果有代码重复调用的地方,一定要使用mas_remakeConstraints,以此防止循环的时候生成相同的约束,影响性能,甚至,能使用make的地方基本都可以用remake进行代替,防止生成无谓的约束

2.关于更新约束布局相关的API

- (void)updateConstraintsIfNeeded  //调用此方法,如果有标记为需要重新布局的约束,则立即进行重新布局,内部会调用updateConstraints方法
- (void)updateConstraints          //重写此方法,内部实现自定义布局过程
- (BOOL)needsUpdateConstraints     //当前是否需要重新布局,内部会判断当前有没有被标记的约束
- (void)setNeedsUpdateConstraints  //标记需要进行重新布局

3.Masonry的属性

@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;

注意:其中leading与left trailing与right 在正常情况下是等价的 但是当一些布局是从右至左时,则会对调 换句话说就是基本不用, 用left和right就好了。用leading/trailing 后就不要用left/right,如果混用会出现崩溃。

4.Masonry的简单使用

<1>.简单示例

UIView *view = [[UIView alloc] init];
view.backgroundColor = [UIColor redColor];
//一定要先加入父控件,否则报错
[self.view addSubview:view];
[view mas_makeConstraints:^(MASConstraintMaker *make) {
    make.edges.equalTo(view.superview).insets(UIEdgeInsetsMake(20, 20, 20, 20));
}];
等价代码
[view mas_makeConstraints:^(MASConstraintMaker *make) {
    make.left.right.top.bottom.equalTo(view.superview).insets(UIEdgeInsetsMake(20, 20, 20, 20));
}];
等价代码
[view mas_makeConstraints:^(MASConstraintMaker *make) {
    make.left.equalTo(view.superview).offset(20);
    make.top.equalTo(view.superview).offset(20);
    make.right.equalTo(view.superview).offset(-20);
    make.bottom.equalTo(view.superview).offset(-20);
}];

注意:链式语法中,and 以及 with都是修饰性语句,不做任何事情,只是便于理解。

<2>.关于multipliedBy的使用

//自视图的宽高是父视图一半
[view mas_makeConstraints:^(MASConstraintMaker *make) {
    make.left.equalTo(view.superview);
    make.top.equalTo(view.superview).offset(20);
    make.width.height.equalTo(view.superview).multipliedBy(0.5);
}];

<3>.关于greaterThanOrEqualTo/lessThanOrEqualTo的使用

//宽大于等于200
make.width.greaterThanOrEqualTo(@200);
//宽小于等于200
make.width.lessThanOrEqualTo(@400)

<4>修改指定约束

MASConstraint *topConstraint;
// 在生成约束的时候
[view1 mas_makeConstraints:^(MASConstraintMaker *make) {
    topConstraint = make.top.equalTo(superview.mas_top);
    make.left.equalTo(superview.mas_left);
}];
// 在之后进行对该约束 进行修改
[topConstraint uninstall];

//blcok中进行判断使用约束(在统一处理某些业务的时候)
[self.button mas_remakeConstraints:^(MASConstraintMaker *make) {
    make.size.equalTo(self.buttonSize);
    if (topLeft) {
        make.top.and.left.offset(10);
    } else {
        make.bottom.and.right.offset(-10);
    }
}];

<5>固定宽高

//固定宽高300*300
[view mas_makeConstraints:^(MASConstraintMaker *make) {
    make.center.equalTo(view.superview);
    make.width.height.equalTo(@300);
}];

<6>关于mas_equalTo/mas_offset()使用

//高度为300的约束中,可以这样子写
mak.height.equalTo(@300);
//也可以,使用mas_equalTo,一般情况下,使用mas_equalTo来处理基本数据类型的封装
mak.height.mas_equalTo(300);

如果想使用基础数据类型当做参数,Masonry为我们提供了"mas_xx"格式的宏定义。
这些宏定义会将传入的基础数据类型转换为NSNumber类型,这个过程叫做封箱(Auto Boxing)。
"mas_xx"开头的宏定义,内部都是通过MASBoxValue()函数实现的。
这样的宏定义主要有四个,分别是mas_equalTo()、mas_offset()和大于等于、小于等于四个。

mas_equalTo其实是多了一层处理的宏而已,因为equalTo并不支持基本数据类型
#define mas_equalTo(...)                equalTo(MASBoxValue((__VA_ARGS__)))

<7>多个视图的等高、等宽、左对齐、下对齐等的约束

// 表达三个视图等高的约束.
make.height.equalTo(@[view1.mas_height, view2.mas_height]);
make.height.equalTo(@[view1, view2]);
make.left.equalTo(@[view1, @100, view3.right]);

<8>动画问题

//动画问题,和普通的方法实现差不多,重点只是修改约束后调用
[view.superview layoutIfNeeded];

[view mas_makeConstraints:^(MASConstraintMaker *make) {
    make.top.mas_equalTo(400);
    make.left.mas_equalTo(100);
    make.size.mas_equalTo(CGSizeMake(100, 100));
}];
//如果其约束还没有生成的时候需要动画的话,就请先强制刷新后才写动画,否则所有没生成的约束会直接跑动画
[view.superview layoutIfNeeded];
    [UIView animateWithDuration:3 animations:^{
        [view mas_updateConstraints:^(MASConstraintMaker *make) {
            make.left.mas_equalTo(200);
    }];
    [view.superview layoutIfNeeded];//强制绘制
}];

<9>设置约束优先级

Masonry为我们提供了三个默认的方法,priorityLow()、priorityMedium()、priorityHigh(),这三个方法内部对应着不同的默认优先级。
除了这三个方法,我们也可以自己设置优先级的值,可以通过priority()方法来设置。

[self.redView mas_makeConstraints:^(MASConstraintMaker *make) { 
    make.center.equalTo(self.view); make.width.equalTo(self.view).priorityLow(); 
    make.width.mas_equalTo(20).priorityHigh(); 
    make.height.equalTo(self.view).priority(200); 
    make.height.mas_equalTo(100).priority(1000); 
}];

Masonry也帮我们定义好了一些默认的优先级常量,分别对应着不同的数值,优先级最大数值是1000。

static const MASLayoutPriority MASLayoutPriorityRequired = UILayoutPriorityRequired; 
static const MASLayoutPriority MASLayoutPriorityDefaultHigh = UILayoutPriorityDefaultHigh; 
static const MASLayoutPriority MASLayoutPriorityDefaultMedium = 500; 
static const MASLayoutPriority MASLayoutPriorityDefaultLow = UILayoutPriorityDefaultLow;
static const MASLayoutPriority MASLayoutPriorityFittingSizeLevel = UILayoutPriorityFittingSizeLevel;

5.Masonry的注意事项

<1> 使用 mas_makeConstraints方法的元素必须事先添加到父元素的中,例如

[self.view addSubview:view];

<2> multipliedBy的使用只能是设置同一个控件的,比如这里的bottomInnerView,

make.height.mas_equalTo(bottomInnerView.mas_width).multipliedBy(3);

<3> 对label约束必须设置最大约束的宽度

self.titleLabel.preferredMaxLayoutWidth = w - 100 - 15;

<4> contentView的冲突
如果遇到和contentView的冲突,基本原因是因为cell的content view有一个系统的约束(高度),而masonry是不会去管理非自己产生的约束,因此在使用label imageview等情况下,增加以下属性设置,确保优先级以防止冲突

[_contentLabel setContentHuggingPriority:UILayoutPriorityRequired forAxis:UILayoutConstraintAxisVertical];

6.Masonry使用问题、修改冲突

当约束冲突发生的时候,我们可以设置view的key来定位是哪个

viewredView.mas_key =@"redView";greenView.mas_key = @"greenView";blueView.mas_key = @"blueView";

若是觉得这样一个个设置比较繁琐,怎么办呢,Masonry则提供了批量设置的宏

MASAttachKeysMASAttachKeys(redView,greenView,blueView); //一句代码即可全部设置。

如果出现什么疑难杂症的话,基本都是AutoLayout在iOS的不适用,所以搜索问题的话,各位直接搜索Autolayout 关键字便可,不必搜索Masonry的问题。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,874评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,102评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,676评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,911评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,937评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,935评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,860评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,660评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,113评论 1 308
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,363评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,506评论 1 346
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,238评论 5 341
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,861评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,486评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,674评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,513评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,426评论 2 352

推荐阅读更多精彩内容

  • Masonry是一个轻量级的布局框架,它拥有自己的描述语法(采用更优雅的链式语法封装)来自动布局,具有很好可读性且...
    AngeloD阅读 3,295评论 0 9
  • Masonry是一个轻量级的布局框架,拥有自己的描述语法,采用更优雅的链式语法封装自动布局,简洁明了并具有高可读性...
    3dcc6cf93bb5阅读 1,762评论 0 1
  • (一)Masonry介绍 Masonry是一个轻量级的布局框架 拥有自己的描述语法 采用更优雅的链式语法封装自动布...
    木易林1阅读 2,331评论 0 3
  • [置顶]iOS - Masonry使用中的一些整理 标签:iOS资源大全iOS常用方法iOS学习资料Masonry...
    DreamMakerSky阅读 3,165评论 0 4
  • 安徒生说,小美人鱼为了与心爱的王子在一起,把自己的鱼尾换成了双腿,却步步扎心,如同走在刀刃上一般。然而自始至...
    凌远远阅读 259评论 0 0