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 全局搜索,可以搜索代码.设置等. 如果 ...
随机推荐
- 安全机密管理:Asp.Net Core中的本地敏感数据保护技巧
前言 在我们开发过程中基本上不可或缺的用到一些敏感机密数据,比如SQL服务器的连接串或者是OAuth2的Secret等,这些敏感数据在代码中是不太安全的,我们不应该在源代码中存储密码和其他的敏感数据, ...
- Quartus prime 的安装步骤:
- SAP集成技术(九)集成能力中心(ICC)
本文链接:https://www.cnblogs.com/hhelibeb/p/17867473.html 内容摘录自<SAP Interface Management Guide>. 定 ...
- Ubuntu开启root账户登陆
Ubuntu开启root账户登陆 设置 root 密码:sudo passwd root sudo chmod 777 /usr/share/lightdm/lightdm.conf.d/50-xx ...
- PhiData 一款开发AI搜索、agents智能体和工作流应用的AI框架
引言 在人工智能领域,构建一个能够理解并响应用户需求的智能助手是一项挑战性的任务.PhiData作为一个开源框架,为开发者提供了构建具有长期记忆.丰富知识和强大工具的AI助手的可能性.本文将介绍Phi ...
- Python读Excel数据自动化填入日常办公的网页表单
前言 本篇内容,让你完全掌握Python是如何自动化办公的~ 一.环境准备 1.1 Python 3.7.0 1.2 Pycharm (Python 开发工具) 1.3 Selenium ...
- 珠排序算法C# 简单实现 奇葩排序中的算盘排序(算珠排序)算法
Console.WriteLine("Hello World!"); int[] arr = { 1, 3, 4, 0, 22, 4,0, 6, 3,10,8,6,7 }; Con ...
- MLP实现minist数据集分类任务
1. 数据集 minist手写体数字数据集 2. 代码 ''' Description: Author: zhangyh Date: 2024-05-04 15:21:49 LastEditTime: ...
- Android桌面Launcher源码浅析
在Android启动过程-万字长文(Android14)中介绍了Android系统的启动过程,本篇文章将继续介绍桌面应用Launcher. 一.Launcher介绍 在Android启动过程-万字长文 ...
- NOIP模拟62
T1 Set 解题思路 抽屉原理 发现对于前缀和向 \(n\) 取模之后一定是右两个值相等的(包括什么都不选的 0 ). 假设 \(pre_j=pre_i\) 那么 \([j+1,i]\) 之间这一段 ...