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会根据自有逻辑来进行处理,但显然作为开发我们肯定想这个逻辑规则牢牢把握在自己手上,比如下面这段代码,widthright明显出现了冲突,实际上这段代码不互报错,至于会显示什么效果,可能会有很多人一时说不上来。

...
[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并排(列)等宽/距离的实现

要实现这个功能主要仰仗MasonryNSArray+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的进阶使用技巧的更多相关文章

  1. Cocos2D中Action的进阶使用技巧(二)

    大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请多提意见,如果觉得不错请多多支持点赞.谢谢! hopy ;) 上回说到解决办法是使用CCTargetedAction类. C ...

  2. Cocos2D中Action的进阶使用技巧(一)

    大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请多提意见,如果觉得不错请多多支持点赞.谢谢! hopy ;) 大家对Cocos2d中动作的使用大概都很清楚了,其实本身act ...

  3. vqmod for opencart插件制作进阶与技巧

    FROM: http://www.sdtclass.com/4799.html 15年的时候,我写过一篇文章<略谈 vqmod for opencart 插件制作过程>,也不知道被哪些人抄 ...

  4. ansible进阶小技巧--tags

    用ansible写playbook的朋友可能会发现,当配置工作很多时,如果在中间过程出错了,修改后想重新执行,前面的一大堆步骤让人感觉很烦躁.虽然提供了“retry”文件,但是却只是根据host来判断 ...

  5. SQL优化之SQL 进阶技巧(上)

    由于工作需要,最近做了很多 BI 取数的工作,需要用到一些比较高级的 SQL 技巧,总结了一下工作中用到的一些比较骚的进阶技巧,特此记录一下,以方便自己查阅,主要目录如下: SQL 的书写规范 SQL ...

  6. 渗透测试的WINDOWS NTFS技巧集合

    译者:zzzhhh 这篇文章是来自SEC Consult Vulnerability Lab的ReneFreingruber (@ReneFreingruber),分享了过去几年从各种博客文章中收集的 ...

  7. Web安全工程师(进阶)课程表

    01-SQL注入漏洞原理与利用 预备知识: 了解HTTP协议,了解常见的数据库.脚本语言.中间件.具备基本的编程语言基础. 授课大纲: 第一章:SQL注入基础 1.1 Web应用架构分析1.2 SQL ...

  8. Oracle SQL优化进阶学习

    引言 对于下面的Oracle分页如何优化该段语句: SELECT * FROM (SELECT A.*, ROWNUM RN FROM (SELECT * FROM task_log order by ...

  9. EOS基础全家桶(十五)智能合约进阶2

    简介 今天我们继续补充智能合约的进阶使用技巧,这次的主题是交易,合约内我们除了可以发起内联action的调用,很多使用还需要直接调用其他的合约action或者以交易的形式调用自身的action. 发起 ...

  10. 几个超级好用但很少有人知道的 webstorm技巧

    我总结一些我发现的比较实用的功能,内容来自日常工作中用到的功能.图片来自PPT,是在公司内部的分享. 你不知道的webstorm进阶使用技巧 1.双击shift 全局搜索,可以搜索代码.设置等. 如果 ...

随机推荐

  1. [ML] 科学编程语言 Octave 简单操作

    octave 是和 matlab 类似的软件,可以方便的进行矩阵计算.图形绘图. matlab 收费,octave 是 gnu 开源软件. Mac 安装: $ brew install octave ...

  2. dotnet 读 WPF 源代码笔记 WriteableBitmap 的渲染和更新是如何实现

    在 WPF 框架提供方便进行像素读写的 WriteableBitmap 类,本文来告诉大家在咱写下像素到 WriteableBitmap 渲染,底层的逻辑 之前我使用 WriteableBitmap ...

  3. Vue3 和 Vue2 的异同及开发中具体区别

    目录 总体来说 性能提升 树摇(Tree shaking) 碎片化节点(Fragment) 传送门 (Teleport) Suspense 更好的TypeScript支持 Composition AP ...

  4. Elasticsdump 数据导入/导出

    目录 一.安装过程 安装NODE 通过npm安装elasticdump 二.数据导出 实操一 实操二 实操三 三.文件导入 一.安装过程 当前工具主要是用来对ES中的数据进行数据导入/导出,以及对数据 ...

  5. python教程1.1:环境安装+代码编辑器安装

    1.环境安装 打开官⽹ https://www.python.org/downloads/windows/ 下载中 下载后执⾏,点击下⼀步安装就⾏,注意选择添加Python到当前⽤户环境变量 2.代码 ...

  6. typescript基础知识汇总

    JavaScript中所有事物(字符串.数值.数组.函数)都是对象,都有属性和方法.1.用函数定义对象,然后new对象实例.2.用Object定义并创建对象实例var o = new Object(t ...

  7. 80x86汇编—分支循环程序设计

    文章目录 查表法: 实现16进制数转ASCII码显示 计算AX的绝对值 判断有无实根 地址表形成多分支 从100,99,...,2,1倒序累加 输入一个字符,然后输出它的二进制数 大小写转换 大写转小 ...

  8. USRP B210 软件定义的无线网络(SDR)支撑设备

    目录 文章目录 目录 蜂窝网络 蜂窝网络的组成 USRP B210 USRP B210 的功能清单与相关参数 USRP B210 的系统结构与运行原理 相关知识储备 SDR RFIC RF 发展历程 ...

  9. pageoffice6 在线编辑 word 文件时禁止拷贝到外部

    有些特殊情况下,希望用户可以在线编辑Word文档,也允许用户拷贝本地电脑或网络上的资料到Word文档中进行编辑,但是不希望用户把在线Word文档中的内容另存到本地或选择并拷贝出去,此时只是禁用另存.禁 ...

  10. VSCode:让VSCode终端面板显示到右边

    很简单,右击下方终端面板,选中"将视图移动到侧面板": 可以看到终端成功显示到右边了: