Masonry的进阶使用技巧
Masonry是iOS开发中常见的视图约束框架,但是有人对他的使用还是浅尝辄止,接下来会提出几点比较少见但是又十分便捷的使用技巧。
mas_greaterThanOrEqualTo
mas_greaterThanOrEqualTo顾名思义是不直接设置该约束,但是限制该约束不要超出边界,比如我们想让UILabel根据文本自适应长度(或高度)的话,就可以这么使用。
UILabel *textLb = [UILabel new];
textLb.font = [UIFont systemFontOfSize:30];
textLb.textColor = [UIColor redColor];
textLb.text = @"MrYu4";
[self.view addSubview:textLb];
[textLb mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.mas_equalTo(400);
make.left.mas_equalTo(10);
make.height.mas_equalTo(33);
make.width.mas_greaterThanOrEqualTo(0);
}];
效果图如下,看得出来文本视图的宽度跟文字长度正好适配。

除了与width/height搭配来约束宽/高之外,也可以与left/right约束在边界。
另外mas_lessThanOrEqualTo则是相反的功能,但也是相同的用法。
priority
看这段代码,猜一下textLb的高度会是比较高还是比较矮。
.......
[textLb mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.mas_equalTo(400);
make.left.mas_equalTo(10);
make.height.mas_equalTo(100).priorityHigh();
make.height.mas_equalTo(33).priorityMedium();
make.width.mas_greaterThanOrEqualTo(0);
}];

图中可以看出priorityHigh()那句代码优先级更高,在Masonry中两个会冲突的约束可以用这三个优先级来手动设定哪个优先级更高
- (MASConstraint * (^)(void))priorityLow;
- (MASConstraint * (^)(void))priorityMedium;
- (MASConstraint * (^)(void))priorityHigh;
(三句话什么意思就不用我多说了吧)
当两个会冲突的约束同时出现时,其实Masonry会根据自有逻辑来进行处理,但显然作为开发我们肯定想这个逻辑规则牢牢把握在自己手上,比如下面这段代码,width和right明显出现了冲突,实际上这段代码不互报错,至于会显示什么效果,可能会有很多人一时说不上来。
...
[textLb mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.mas_equalTo(400);
make.left.mas_equalTo(self.view.mas_right).offset(-70);
make.height.mas_equalTo(33);
make.right.mas_equalTo(-5);
make.width.mas_equalTo(100);
}];
这时候我们要做的就是添加上优先级(优先级落后的也要加上),这样子代码就会顺着我们的想法去走,比如我要求的是宁愿超出屏幕也要宽度保证为100,就可以这么写。
...
make.right.mas_equalTo(-5).priorityMedium();
make.width.mas_equalTo(100).priorityHigh();

父视图大小适配子视图的大小
有时候一个view的大小需要其子视图来确认(尤其是其子视图的大小还可能需要等服务器返回数据之后才能确认其大小),这个时候我们其实不需要学习到什么新的方法,只需要在设置父视图时添加对子视图的依赖即可。
//此处是父视图
UIView *blueView = [UIView new];
blueView.backgroundColor = [UIColor blueColor];
//下面是两个子视图
UILabel *textLb = [UILabel new];
textLb.font = [UIFont systemFontOfSize:30];
textLb.textColor = [UIColor redColor];
[blueView addSubview:textLb];
[textLb mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.mas_equalTo(0);
make.left.mas_equalTo(20);//表示其在父视图左边距20处,相对来讲,父视图至少左侧有20长度的宽度了
make.height.mas_equalTo(33);
make.width.mas_greaterThanOrEqualTo(0);
}];
UILabel *textLb2 = [UILabel new];
textLb2.font = [UIFont systemFontOfSize:30];
textLb2.textColor = [UIColor redColor];
[blueView addSubview:textLb2];
[textLb2 mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.mas_equalTo(textLb);
make.left.mas_equalTo(textLb.mas_right);
make.height.mas_equalTo(33);
make.width.mas_greaterThanOrEqualTo(0);
}];
[self.view addSubview:blueView];
[blueView mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.mas_equalTo(400);
make.left.mas_equalTo(12);
make.right.mas_equalTo(textLb2);//关键点
make.height.mas_equalTo(70);
}];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC * 2), dispatch_get_main_queue(), ^{
//模拟服务器返回数据
textLb.text = @"MrYu4";
textLb2.text = @"服务器返回文字";
});

还有的朋友把子视图写在父视图的类里面,处理方法也是同理的,只需要注意的时候不要把写好的约束给覆盖甚至移除掉就好了。
多个view并排(列)等宽/距离的实现
要实现这个功能主要仰仗Masonry中NSArray+MASAdditions.h,核心思路就是将所有的view放入数组中,并将这个数组合并成一个个体来思考。
1、实现相同约束
NSArray+MASAdditions.h实现了和UIView+MASAdditions.h同名的方法,当我们想让数组里的view各个添加一样的约束时,直接对数组添加就好。
//@interface NSArray (MASAdditions)
- (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;
也许大聪明还在用
for循环来对每个view添加相同约束,其实上面的方法就是这些大聪明的做法的封装。- (NSArray *)mas_makeConstraints:(void(^)(MASConstraintMaker *make))block {
NSMutableArray *constraints = [NSMutableArray array];
for (MAS_VIEW *view in self) {
NSAssert([view isKindOfClass:[MAS_VIEW class]], @"All objects in the array must be views");
//注意这个[view mas_makeConstraints:block],还有估计有人还没注意到两边的同名方法其实是有返回值的(返回约束数组)
[constraints addObjectsFromArray:[view mas_makeConstraints:block]];
}
return constraints;
}
2、平均排列
NSArray+MASAdditions.h还有两个未提及的方法,此刻可以派上用场了。
/**
* distribute with fixed spacing
*
* @param axisType which axis to distribute items along
* @param fixedSpacing 每个item之间的距离
* @param leadSpacing the spacing before the first item and the container
* @param tailSpacing the spacing after the last item and the container
*/
- (void)mas_distributeViewsAlongAxis:(MASAxisType)axisType withFixedSpacing:(CGFloat)fixedSpacing leadSpacing:(CGFloat)leadSpacing tailSpacing:(CGFloat)tailSpacing;
/**
* distribute with fixed item size
*
* @param axisType which axis to distribute items along
* @param fixedItemLength 每个item的长度
* @param leadSpacing the spacing before the first item and the container
* @param tailSpacing the spacing after the last item and the container
*/
- (void)mas_distributeViewsAlongAxis:(MASAxisType)axisType withFixedItemLength:(CGFloat)fixedItemLength leadSpacing:(CGFloat)leadSpacing tailSpacing:(CGFloat)tailSpacing;
两个方法只有一个参数不一样,也体现了二者方法使用场景的不同:
- item距离固定,item宽度根据父视图空间适应
- item宽度固定,item间距离根据父视图空间适应
3、代码
目标:蓝色view作为父视图,有红黄绿各三个view距离固定为10,等宽显示。
NSArray <UIView *>*views = @[redView,yellowView,greenView];
[views mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.bottom.mas_equalTo(0);
}];
[views mas_distributeViewsAlongAxis:MASAxisTypeHorizontal
withFixedSpacing:10
leadSpacing:0
tailSpacing:0];

Masonry的进阶使用技巧的更多相关文章
- Cocos2D中Action的进阶使用技巧(二)
大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请多提意见,如果觉得不错请多多支持点赞.谢谢! hopy ;) 上回说到解决办法是使用CCTargetedAction类. C ...
- Cocos2D中Action的进阶使用技巧(一)
大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请多提意见,如果觉得不错请多多支持点赞.谢谢! hopy ;) 大家对Cocos2d中动作的使用大概都很清楚了,其实本身act ...
- vqmod for opencart插件制作进阶与技巧
FROM: http://www.sdtclass.com/4799.html 15年的时候,我写过一篇文章<略谈 vqmod for opencart 插件制作过程>,也不知道被哪些人抄 ...
- ansible进阶小技巧--tags
用ansible写playbook的朋友可能会发现,当配置工作很多时,如果在中间过程出错了,修改后想重新执行,前面的一大堆步骤让人感觉很烦躁.虽然提供了“retry”文件,但是却只是根据host来判断 ...
- SQL优化之SQL 进阶技巧(上)
由于工作需要,最近做了很多 BI 取数的工作,需要用到一些比较高级的 SQL 技巧,总结了一下工作中用到的一些比较骚的进阶技巧,特此记录一下,以方便自己查阅,主要目录如下: SQL 的书写规范 SQL ...
- 渗透测试的WINDOWS NTFS技巧集合
译者:zzzhhh 这篇文章是来自SEC Consult Vulnerability Lab的ReneFreingruber (@ReneFreingruber),分享了过去几年从各种博客文章中收集的 ...
- Web安全工程师(进阶)课程表
01-SQL注入漏洞原理与利用 预备知识: 了解HTTP协议,了解常见的数据库.脚本语言.中间件.具备基本的编程语言基础. 授课大纲: 第一章:SQL注入基础 1.1 Web应用架构分析1.2 SQL ...
- Oracle SQL优化进阶学习
引言 对于下面的Oracle分页如何优化该段语句: SELECT * FROM (SELECT A.*, ROWNUM RN FROM (SELECT * FROM task_log order by ...
- EOS基础全家桶(十五)智能合约进阶2
简介 今天我们继续补充智能合约的进阶使用技巧,这次的主题是交易,合约内我们除了可以发起内联action的调用,很多使用还需要直接调用其他的合约action或者以交易的形式调用自身的action. 发起 ...
- 几个超级好用但很少有人知道的 webstorm技巧
我总结一些我发现的比较实用的功能,内容来自日常工作中用到的功能.图片来自PPT,是在公司内部的分享. 你不知道的webstorm进阶使用技巧 1.双击shift 全局搜索,可以搜索代码.设置等. 如果 ...
随机推荐
- WPF 项目文件不加 -windows 的引用 WPF 框架方式
默认情况下的 WPF 项目都是带 -windows 的 TargetFramework 方式,但有一些项目是不期望加上 -windows 做平台限制的,本文将介绍如何实现不添加 -windows 而引 ...
- dotnet 警惕 ConcurrentDictionary 使用 FirstOrDefault 获取到非预期的首项
在 dotnet 里面的 ConcurrentDictionary 是一个支持并发读写的线程安全字典,在这个字典里面有一些行为会出现随机性,即多次执行相同的代码返回的结果可能不相同.本文记录在 Con ...
- 使用亚马逊AWS云服务器进行深度学习——免环境配置/GPU支持/Keras/TensorFlow/OpenCV
前言 吐槽:由于科研任务,需要在云端运行一个基于神经网络的目标识别库,需要用到GPU加速.亚马逊有很多自带GPU的机器,但是环境的配置可折腾坏了,尤其是opencv,每次总会出各种各样的问题! 无奈中 ...
- ABAP RSA 加密
最近出现一些SAP ABAP RSA加密的需求,这里搬运一篇文章,用于学习参考. 本文链接:https://www.cnblogs.com/hhelibeb/p/14952732.html 原文标题: ...
- All in One:Prometheus 多实例数据统一管理最佳实践
01 引言 Prometheus 作为目前最主流的可观测开源项目之一,已经成为云原生监控的事实标准,被众多企业广泛应用.在使用 Prometheus 的时候,我们经常会遇到全局视图的需求,但是数据确分 ...
- 12、web 中间件加固-apache 加固
1.账号设置 1.1.防止 webshell 越权使用 修改 httpd.conf:/etc/httpd/conf/httpd.conf 或编译路径下 /conf/httpd.conf 检查程序启动账 ...
- ACM算法竞赛代码模板(长期更新)
C++算法模板 基础算法 排序 快速排序 void quickSort(int q[], int l, int r) { if (l >= r) return; int i = l - 1, j ...
- C语言:实现数组的删除和增加
/* 删除方法: 如:12 32 56 84 95 用覆盖的方法 若删除第三个,则第四个要覆盖第三个,第五个要覆盖第四个 覆盖完:12 32 84 ...
- Clion代码自动格式化保存
目录 前言 使用外部工具Artistic Style Clion 插件配置 注意 前言 使用Clion的时候,可以自动格式化代码的操作. 使用外部工具Artistic Style 序号 名称 地址 1 ...
- 【PB案例学习笔记】-01创建应用、窗口与控件
写在前面 这是PB案例学习笔记系列文章的第一篇,也是最基础的一篇.后续文章中[创建程序基本框架]部分操作都跟这篇文章一样, 将不再重复.该系列文章是针对具有一定PB基础的读者,通过一个个由浅入深的编程 ...