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 全局搜索,可以搜索代码.设置等. 如果 ...
随机推荐
- [Ethereum] 浅谈加密商品市场 OpenSea 与 opensea-js
OpenSea 是用于交易以太坊加密商品的网上商店,主要的商品是 ERC721.ERC1155 标准的 Token. 它的特色就在于,只需要一个部署好的智能合约,你就能在 OpenSea 提供的界面上 ...
- [Contract] Solidity 合约发布到测试网 ropsten 的作用
当我们本地完成了一系列测试以后,接下来就是准备上线了. 关于合约部署可以参考这篇:Solidity 合约使用 truffle 部署到测试网和主网 你可能有一个疑问,在上主网之前,先上测试网的作用是什么 ...
- kubeadm搭建单master多node节点的k8s集群(3)
一.实验环境准备 K8s集群角色 IP 主机名 安装的组件 配置 控制节点 192.168.1.10 master apiserver.controller-manager.scheduler.etc ...
- Linux内核之I2C协议
I2C协议标准文档 THE I2C-BUS SPECIFICATION VERSION 2.1 JANUARY 2000: https://www.csd.uoc.gr/~hy428/reading/ ...
- vue通过input选取图片,jq的ajax向服务器上传img
<template> <div class=""> <!-- 选择后预览 --> <img v-if="im ...
- VUE+element页面按钮调用dialog
VUE+element通过按钮调用普通弹框(弹框页面独立出一个dialog页面,非在同一个页面文件里) 代码如下 <el-dialog> <el-button type=" ...
- SpringMVC学习五(resultful风格/异常处理/注解)
resultful风格 异常处理 1.Restfule风格 Restfule风格是一种软件架构风格,而不是标准,只是提供了一种设计原则和约束条件.主要适用于客户端和服务器端交互的软件.是基于http协 ...
- RAC关闭【Oracle 10g】
顺序:关闭监听->关闭实例->关闭服务->关闭软件 1.关闭监听 进入节点1,[oracle@arprac01 ~]$lsnrctl stop 进入节点2,[oracle@arpra ...
- 08 ES基本的聚合查询
目录 按protocol聚合 指定地区,按port聚合 指定地区和时间段,按ip聚合(独立ip 即ip去重) 并且 聚合再求独立ip数 聚合后将聚合结果进行分页的解决办法 子聚合 按protocol聚 ...
- 几行命令用minikube快速搭建可测试的kubernetes单节点环境
几行命令用minikube快速搭建可测试的kubernetes单节点环境 需要docker环境,https://www.cnblogs.com/xiaofei12/p/17544579.html,网速 ...