博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
iOS Autolayout 之 Masonry 使用
阅读量:5930 次
发布时间:2019-06-19

本文共 7882 字,大约阅读时间需要 26 分钟。

Masonry介绍

是一个轻量级的布局框架 拥有自己的描述语法 采用更优雅的链式语法封装NSAutoLayout, 简洁明了并具有高可读性 而且同时支持 iOS 和 Max OS X。使用Masonry能够使用简单的语法进行Autolayout布局

Masonry常用属性与NSLayoutAttrubute的对照表如下

Masonry NSAutoLayout 说明
view.mas_left NSLayoutAttributeLeft 左侧
view.mas_top NSLayoutAttributeTop 上侧
view.mas_right NSLayoutAttributeRight 右侧
view.mas_bottom NSLayoutAttributeBottom 下侧
view.mas_leading NSLayoutAttributeLeading 首部
view.mas_trailing NSLayoutAttributeTrailing 尾部
view.mas_width NSLayoutAttributeWidth
view.mas_height NSLayoutAttributeHeight
view.mas_centerX NSLayoutAttributeCenterX 横向中点
view.mas_centerY NSLayoutAttributeCenterY 纵向中点
view.mas_baseline NSLayoutAttributeBaseline 文本基线

使用Masonry进行Autolayout布局

Masonry三种Autolayout Compare类型

  • .equalTo 相当于NSLayoutRelationEqual,为相等
  • .lessThanOrEqualTo相当于 NSLayoutRelationLessThanOrEqual,为小于或者等于
  • .greaterThanOrEqualTo 相当于 NSLayoutRelationGreaterThanOrEqual,为大于或等于
// **使用UIView/NSView进行比较**    [view1 mas_makeConstraints:^(MASConstraintMaker *make) {            //these two constraints are exactly the same            make.left.greaterThanOrEqualTo(label.mas_left);            make.left.right.equalTo(lable);        }];        ..    //2. **直接使用NSNumber进行比较**    [view1 mas_makeConstraints:^(MASConstraintMaker *make) {            //width >= 200 && width <= 400            make.width.greaterThanOrEqualTo(@200);            make.width.lessThanOrEqualTo(@400)    }];    ..    //3. **使用CGFloat**    [subGreenView mas_makeConstraints:^(MASConstraintMaker *make) {            //width >= 200 && width <= 400            make.width.mas_lessThanOrEqualTo(200);            make.width.mas_greaterThanOrEqualTo(400);    }];复制代码

两个同级的view进行约束

[subGreenView mas_makeConstraints:^(MASConstraintMaker *make) {            make.left.equalTo(subGreenView.mas_left).offset(10);            make.right.equalTo(subGreenView.mas_right).offset(10);    }];复制代码

left, right, top, bottom, centerX, centerY, leading, trailing, width, height

可以通过mas_makeConstraints关联View的left, right, top, bottom, centerX, centerY, leading, trailing, width, height 进行布局。

  1. 使用UIView/NSView进行布局
[view1 mas_makeConstraints:^(MASConstraintMaker *make) {            make.top.equalTo(sv).with.offset(5); //with 不是必要的,只是方便理解            make.left.equalTo(sv).with.offset(10);            make.bottom.equalTo(sv).offset(15);            make.right.equalTo(sv).offset(20);    }];复制代码

或者

[subRedView mas_makeConstraints:^(MASConstraintMaker *make) {            make.top.equalTo(subRedView);            make.left.equalTo(subRedView);            make.width.equalTo(subRedView);            make.height.equalTo(subRedView);    }];复制代码
  1. 直接使用NSNumber进行布局
[subRedView mas_makeConstraints:^(MASConstraintMaker *make) {            make.top.equalTo(@18);            make.left.equalTo(@16);            make.width.equalTo(@16);            make.height.equalTo(@16);    }];复制代码
  1. 直接使用CGFloat进行布局
[subRedView mas_makeConstraints:^(MASConstraintMaker *make) {            make.centerX.mas_equalTo(18);            make.centerY.mas_equalTo(16);            make.width.mas_equalTo(16);            make.height.mas_equalTo(16);    }];复制代码
  1. NSArray
[view1 mas_makeConstraints:^(MASConstraintMaker *make) {        make.height.equalTo(@[view1, view2]);        make.left.equalTo(@[view1, @100, view3.right]);    }];复制代码

数组有多个不合理的值时,总是获取最小值来使用.相当于来取最小值.An array of a mixture of any of the previous types

edges, size, center

  • make.edges 相当于同时设置 MASAttributeTop ,MASAttributeLeft , MASAttributeRight , MASAttributeBottom
  • make.size 相当于同时设置 MASAttributeWidth , MASAttributeHeight
  • make.center 相当于同时设置 MASAttributeCenterX, MASAttributeCenterY
[view1 mas_makeConstraints:^(MASConstraintMaker *make) {            make.edges.equalTo(superview).insets(UIEdgeInsetsMake(5, 10, 15, 20));            make.size.equalTo(superview).sizeOffset(CGSizeMake(100, 50));            make.center.equalTo(superview).centerOffset(CGPointMake(-5, 10));    }];复制代码

相当于

[view1 mas_makeConstraints:^(MASConstraintMaker *make) {            //.insets            make.top.equalTo(sv).with.offset(5);            make.left.equalTo(sv).with.offset(10);            make.bottom.equalTo(sv).with.offset(-15);//使用offset,统一方向,所以这里是-15            make.right.equalTo(sv).with.offset(-20);// 统一方向.            //.size            make.width.equalTo(sv).offset(100);            make.height.equalTo(sv).offset(50);            //.centerOfoffset            make.centerX.equalTo(sv).offset(-5);            make.centerY.equalTo(sv).offset(10);    }];复制代码

Masonryz 设置优先级: 优先级有四种方式:

  • .priority 来设定一个明确地优先级的值,是有参数的
  • .priorityHigh 没有参数,使用默认的MASLayoutPriorityDefaultHigh值
  • .priorityMedium,使用默认的MASLayoutPriorityDefaultMedium值
  • .priorityLow,使用默认的MASLayoutPriorityDefaultLow值.
    与NSAutolayout类似,Masonry会优先实现优先级高的设定,发生冲突时,放弃优先级低的设定.

持有并在其他时间进行自动布局的更新

如果要定义需要进行自动布局更新的约束。比如通过这约束存在来进行动画效果状态更新,或者更新删除约束.
Masonry中有三种方法来更新约束constraints.

  1. mas_updateConstraints
    使用mas_updateConstraints可以用来更新视图的约束,而mas_makeConstraints只能用来创建约束.
    一般是先创建约束,然后在合适的地方使用mas_updateConstraints来更新视图约束.
[self.likeNumberView mas_updateConstraints:^(MASConstraintMaker *make) {        make.top.equalTo(self.locationView.mas_bottom)        .offset(kTopOffsetOfLikeNumberView);        make.height.mas_equalTo(kHeightOfLikeNumberView);    }];复制代码
  1. mas_remakeConstraints
    mas_updateConstraints只能用来更新约束,但是只能更新已有约束的值,不能删除已有约束.
    而使用mas_remakeConstraints的使用方法与mas_updateConstraints相同,但是它在更新视图之前,会删除之前所有约束,然后再创建新的约束来更新视图.
[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);            }    }];复制代码
  1. References
    也可以通过持有一个 MASConstraint类型的约束保持在本地,然后通过installuninstall方法来使用和删除该约束
    用起来比前两个复杂,但是灵活性很强,可以同时删除和更新约束。
@property (nonatomic, strong) MASConstraint *topConstraint;..[subRedView mas_makeConstraints:^(MASConstraintMaker *make) {_topConstraint = make.top.equalTo(superView.mas_top).with.offset(10);//这里是保存了已经设定好的约束make.left.equalTo(superView.mas_left).with.offset(10);}];..//之后需要取消的时候[_topConstraint uninstall];..//也可以安装[_topConstraint install];复制代码

⚠️Masonry 布局注意事项

  • UILabel 不用设置高度和宽度,设置了高度,字符很容易被截断
  • 设置的约束有冲突,控制台会输出错误log,如
2018-03-28 17:50:55.761481+0800 OMI[7256:2846471] [LayoutConstraints] Unable to simultaneously satisfy constraints.Probably at least one of the constraints in the following list is one you don't want.Try this:(1) look at each constraint and try to figure out which you don't expect;(2) find the code that added the unwanted constraint or constraints and fix it.("
","
","
","
","
","
")复制代码

正如输出中所述,Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger,现在介绍下使用UIViewAlertForUnsatisfiableConstraints的调试方法。

在UIViewAlertForUnsatisfiableConstraints添加symbolic breakpoint:

1.打开断点导航(cmd+7)

2.点击左下角的+按钮
3.选择Add Symbolic Breakpoint
4.在Symbol添加UIViewAlertForUnsatisfiableConstraints
5. 添加po [[UIWindow keyWindow] _autolayoutTrace](OC项目)或expr -l objc++ -O -- [[UIWindow keyWindow] > _autolayoutTrace](Swift项目)

之后你就可以看到哪里出错了:

po [[UIWindow keyWindow] _autolayoutTrace]UIWindow:0x7f9481c93360|   •UIView:0x7f9481c9d680|   |   *UIView:0x7f9481c9d990- AMBIGUOUS LAYOUT for UIView:0x7f9481c9d990.minX{id: 13}, UIView:0x7f9481c9d990.minY{id: 16}|   |   *_UILayoutGuide:0x7f9481c9e160- AMBIGUOUS LAYOUT for _UILayoutGuide:0x7f9481c9e160.minY{id: 17}|   |   *_UILayoutGuide:0x7f9481c9ebb0- AMBIGUOUS LAYOUT for _UILayoutGuide:0x7f9481c9ebb0.minY{id: 27}复制代码

其中AMBIGUOUS相关的视图就是约束有问题的。0x7f9481c9d990就是有问题视图的首地址。可以快速定位到相关子控件。

其他调试技巧

当然进一步的调试需要LLDB的命令。比如

打印视图对象:

(lldb) po 0x7f9481c9d990
>复制代码

改变颜色:

(lldb) expr ((UIView *)0x174197010).backgroundColor = [UIColor redColor](UICachedDeviceRGBColor *) $4 = 0x0000000174469cc0复制代码

剩下的就是去代码中找到这个视图,然后修改其约束了。

延伸资料

转载于:https://juejin.im/post/5ac34f9351882555867f9f12

你可能感兴趣的文章
通过写Babel插件理解抽象语法树(翻译)
查看>>
清华大学马少平:一款智能硬件背后的“AI争霸” ...
查看>>
JavaScript之EventListener事件的传递顺序--冒泡和捕获传播 ...
查看>>
linux 检查那个进程占用文件
查看>>
行业案例——政府部门协同OA解决方案分享
查看>>
【直播回顾】云栖社区特邀专家蒋泽银:Jpom一款低侵入式Java运维、监控软件 ...
查看>>
封装、继承、多态、访问符,范围修饰符
查看>>
.NET(WinCE、WM)开发转Android开发 ——Xamarin和Smobiler对比
查看>>
Prometheus 由于时间不同步导致数据不显示
查看>>
Minikube的安装
查看>>
Dubbo即将毕业,晋升为Apache顶级项目?
查看>>
python学习手册25 OOP:宏伟蓝图
查看>>
关于try...except和try ....except...else
查看>>
RedisManager使用手册(五)-- 自定义Redis安装包
查看>>
灵玖软件:NLPIR数据挖掘助力行业创新发展
查看>>
OTSReader自己定义切分主键
查看>>
SD-WAN技术的详细解析
查看>>
阿里云Redis配置公网连接的注意点
查看>>
“Wel鲸鱼轻烟”收购杭州轻烟科技,并完成千万元Pre-A轮融资
查看>>
野马财经完成A轮融资,起点创投等机构投资
查看>>