Masonry学习分享
不完整目录
1.基础篇
1.1基础使用
1.1.1运行效果
1.1.2关键代码
三个控件等高,红绿两个控件等宽
[greenView mas_makeConstraints:^(MASConstraintMaker *make) {
make.height.mas_equalTo(redView);
make.height.mas_equalTo(blueView)
make.width.mas_equalTo(redView);
}];
黄色在蓝色中居中显示(居中偏移可使用:make.center.equalTo(blueView).centerOffset(CGPointMake(50, 50));)
make.center.equalTo(blueView);
灰色在绿色区域中设置边距
make.edges.equalTo(greenView).insets(UIEdgeInsetsMake(20, 20, 20, 20));
1.2约束百分比
1.2.1运行效果
1.2.2 关键代码
设置宽高比:multipliedBy、 dividedBy
红色高度是页面的1/2
make.height.equalTo(self.view).dividedBy(2);
绿色宽度是自身高度2倍
make.width.mas_equalTo(greenView.mas_height).multipliedBy(2);
设置绿色宽和高不能超过红色
make.width.height.mas_equalTo(redView).priorityLow();
make.width.height.lessThanOrEqualTo(redView);
1.3 UIScrollView使用Masonry
1.3.1 运行效果
1.3.2 关键代码
UIScrollView使用约束比较特殊,在添加到父视图上之后,需设置自己的大小及内容的长度。但对于scrollview和tableview,我们不能使用bottom来计算其高,因为这个属性对于scrollview和tableview来说,不用用来计算高度的,而是用于计算contentSize.height的。所以简单添加约束如下:
//设置其大小
make.edges.mas_equalTo(self.view);
// 让scrollview的contentSize随着内容的增多而变化
make.bottom.mas_equalTo(lastWidget.mas_bottom).offset(20);
这两句即可简单实现UIScrollView在页面中显示,如果页面内容高于屏幕时,可正常滑动,但内容很少时则不能滑动。解决该问题可请参照1.6正确的写法
1.4 单个约束启用、禁用
1.4.1运行效果
页面所有UILabel都设置收缩状态约束高度为40,点击某个label时,该UILabel根据内容大小动画展开,再次点击收缩。页面整体的UIScrollview根据内容高度自动扩展(原理同1.3)
1.4.2 关键代码 MASViewConstraint (void)install (void)uninstall
创建约束或更新约束时,可赋值该约束对象到itemConstraint,注意加__block
[label mas_makeConstraints:^(MASConstraintMaker *make) {
itemConstraint = (MASViewConstraint *)make.height.mas_equalTo(40);
]};
执行约束的装载或卸载,注意,当在UITableViewCell中使用时,由于cell重用的机制,约束的赋值可能存在问题
[itemConstraint install];
[itemConstraint uninstall];
1.5 UITableViewCell中使用约束,及cell高度自动计算
1.5.1运行效果
Cell布局简单来讲分为标题、描述上下两部分,其中描述文字默认收缩,点击时展开,cell高度自动扩充。
1.5.2关键代码 UITableViewCell+HDFTableViewCell
cell中指定作为最后一个视图以及最后一个视图最底部与cell的底部之间的距离
- (void)hdf_setCellLastView:(UIView *)lastView bottomOffset:(CGFloat)bottomOffset;
cell高度自动计算:静态方法自动计算cell高度 configBlock中为cell填充数据
注意:
1、hdf_setCellLastView 可以在cell初始化控件中调用,也可以在控件设置数据方法中调用。
2、cell中控件尽量不要对self.contentView.mas_bottom进行约束。除非该控件与其他控件没有top、bottom关联约束
3、cell中多行UILabel相对cell.contentView尽量使用left+width约束,避免使用left+right,后者容易产生多行文字高度计算不准确问题
4、cell中多行UILabel在iOS6上还需要设置preferredMaxLayoutWidth(项目已不关心iOS6,可忽略)。
5、项目中UITableViewCell+HDFTableViewCell 使用了cell高度的缓存,若要更新高度或者数据源做了改变,记得调用+(void)hdf_removeCellResource
1.6 UIScrollView 应用Masonry的正确用法
1.6.1运行效果
1.6.2 关键代码
scrollView设置edge约束,该约束实际上确定scrollview的frame等于当前Vc视图大小
[self.scrollView mas_makeConstraints:^(MASConstraintMaker *make) {
make.edges.mas_equalTo(self.view);
}];
内容容器设置约束
[scrollContentView mas_makeConstraints:^(MASConstraintMaker *make) {
make.edges.equalTo(self.scrollView); //scrollContentView填满Scrollview
make.width.equalTo(self.scrollView);//等同于设置contentSize宽度
make.height.greaterThanOrEqualTo(self.scrollView).offset(1);//设置contentSize高度,加1像素offset保证内容不足一屏也能滑动
}];
内容容器要知道自己到底多高,所以最后一个控件要加底部约束
[bottomWidget mas_makeConstraints:^(MASConstraintMaker *make) {
make.bottom.equalTo(scrollContentView.mas_bottom).offset(-80);
}];
注意:
UIScrollView 使用Masonry时,尽量不要在scrollview上直接addview。而应该使用一个viewContainer,所有的控件放在viewContainer上。
关键是 !!!设置container与scrollView之间的约束!!!。
scrollView的width或者bottom不能用来计算其Frame,因为这个属性对于scrollview和tableview来说,不用用来计算高度的,而是用于计算contentSize的
设置步骤简单来说:
1、设置scrollview的大小为屏幕大小
2、设置viewContainer宽度为scrollview宽,高度为内容高,但还要填充scrollview
1.7 UITableViewCell中隐藏控件更新布局及高度
1.7.1 运行效果
1.7.2 关键代码
cell中设置最后控件及cell高度计算同 “1.5简单tableview布局”
分为两种情况,如果需要隐藏的控件高度是固定或是frame封装的控件(如果要隐藏的控制在最低端则直接调用hdf_setCellLastView即可,记得将其hidden掉)
if (isHidden) {
[_testCustomView mas_updateConstraints:^(MASConstraintMaker *make) {
make.height.equalTo(@0);
}];
}else{
[_testCustomView mas_updateConstraints:^(MASConstraintMaker *make) {
make.height.equalTo(@100);
}];
}
控件内容非固定,根据内容变化 实现原理是直接把下方控件顶部约束贴到该控件顶部,由于是remake方式,所以原有约束需保留
if (isHidden) {
testCustomView.hidden = YES;
[self.bottomWidget mas_remakeConstraints:^(MASConstraintMaker *make) {
make.top.mas_equalTo(_testCustomView.mas_top);
make.centerX.equalTo(@0);
}];
}else{
testCustomView.hidden = NO;
[self.bottomWidget mas_remakeConstraints:^(MASConstraintMaker *make) {
make.top.mas_equalTo(_testCustomView.mas_bottom);
make.centerX.equalTo(@0);
}];
}
2.动画篇
2.1动画更新、重建约束
2.1.1 运行效果
2.1.2关键代码
updateViewConstraints setNeedsUpdateConstraints
页面中重写updateViewConstraints方法,当然即使不用该回调也可以实现动画,但苹果推荐在updateViewConstraints方法中更新、添加、重建约束;
当我们将update或remake约束代码放到updateViewConstraints这个方法中时,我们在viewDidLoad方法中可以不用再写约束
-(void)updateViewConstraints{
[super updateViewConstraints] 父类方法一定要调用
}
想要更新约束时添加动画,就需要调用关键的一行代码:setNeedsUpdateConstraints,这是选择对应的视图中的约束需要更新。
对于updateConstraintsIfNeeded这个方法并不是必须的,但是有时候不调用就无法起到我们的效果。但是,官方都是这么写的,从约束的更新原理上讲,这应该写上。我们要使约束立即生效,就必须调用layoutIfNeeded此方法。看下面的方法,就是动画更新约束的核心代码
-(void)startAnimation{
//告诉self.view约束需要更新
[self.view setNeedsUpdateConstraints];
//告诉self.view检测是否需要更新约束,若需要则更新,下面添加动画效果才起作用
[self.view updateConstraintsIfNeeded];
//frame更新,执行动画
[UIView animateWithDuration:0.3 animations:^{
[self.view layoutIfNeeded];
}];
}
3.应用篇
3.1 tableHeaderView使用Masonry
3.1.1运行效果
对于一些页面中使用UITableView时,如果头部布局较固定,个人建议使用tableHeaderView,利于代码结构及UI调整。
3.1.2关键代码 layoutIfNeeded
使用frame定义一个customeHeaderView,之所以使用frame是由于tableHeaderView只支持frame来使用,因此不要对customeHeaderView添加约束
customeHeaderView = [[UIView alloc] initWithFrame:(CGRect){0,0,kScreenWidth,100}];
注意!!设置宽度为屏幕宽度而不是0,避免子控件设置宽度约束而报约束冲突警告
customeHeaderView中正常使用Masonry来添加子控件
调用tableView.tableHeaderView = customeHeaderView时,要放在最后。原因很简单:赋予正确的frame
-(void)updateTabelHeaderHeight{
[customeHeaderView layoutIfNeeded];
CGRect headerRect = customeHeaderView.frame;
headerRect.size.height = bottomWidget.frame.origin.y+ bottomWidget.frame.size.height;
customeHeaderView.frame = headerRect;
tableView.tableHeaderView = customeHeaderView;
}当customeHeaderView中高度需要动态变化时,需重新调用上面updateTabelHeaderHeight方法
3.2 内容相对多个控件布局
3.2.1运行效果
(只有一个科室时,图一文字垂直居中显示,图二垂直上对齐)
3.2.2 关键代码
底部绿色Label设置约束为:
make.top.greaterThanOrEqualTo(ivAvatar.mas_bottom).offset(15);
make.top.equalTo(lblVerticalDesc.mas_bottom).offset(15);
如果想要科室文字垂直上对齐如图二,则都设置为greaterThanOrEqualTo
3.3文字区域等宽
3.3.1运行效果
3.3.2关键代码
[lblNum1 mas_remakeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(@15);
make.left.equalTo(ivAvatar.mas_right);
make.width.mas_equalTo(@[lblNum2, lblNum3]);//可以传数组
}];
3.4同向文字显示优先级
3.4.1运行效果
3.4.2关键代码 setContentHuggingPriority setContentCompressionResistancePriority
这两个方法是AutoLayout的api,Masonry是基于AutoLayout的封装。所以可以混合使用,可设置优先级及方向。
ContentCompressionResistance=不许挤我。这个属性的优先级(Priority)越高,越不“容易”被压缩,也就是说,当整体的空间装不下所有的View的时候,ContentCompressionResistance优先级越高的,显示的内容越完整
ContentHugging = 抱紧。 这个属性的优先级越高,整个View就要越“抱紧”View里面的内容。也就是View的大小不会随着父级View的扩大而扩大
[lblHorizontalDesc setContentHuggingPriority:UILayoutPriorityDefaultHigh forAxis:UILayoutConstraintAxisHorizontal];
[lblHorizontalDesc setContentCompressionResistancePriority:UILayoutPriorityDefaultHigh forAxis:UILayoutConstraintAxisHorizontal];
4.问题篇
1、view一定是已经被首先addSubview的(不可以直接对tableHaderView进行约束)
2、约束的设置其实就是告诉系统你的控件各自的相对位置,也就是系统能计算出每个控件的实际frame
3、控制UItableViewCell中控件的高度或调整约束就可以动态适用cell高度计算,
4、cell中控件尽量不要对cell.contentView进行mas_bottom约束,除非这个控件没有mas_top约束;
5、cell中多行的UIlabel使用left、right约束有时会有UILabel高度计算不准确的问题,建议使用left+width;
6、使用Masonry的理念就是不用去计算文字的宽度及高度,如果需要自己计算,看看是不是约束能优化
7、一些基本的控件有内容时可不用设置高度约束,如:UILabel,UIimageView,UIButton等
demo下载链接:
Masonry学习分享的更多相关文章
- ElasticSearch 5学习(7)——分布式集群学习分享2
前面主要学习了ElasticSearch分布式集群的存储过程中集群.节点和分片的知识(ElasticSearch 5学习(6)--分布式集群学习分享1),下面主要分享应对故障的一些实践. 应对故障 前 ...
- ElasticSearch 5学习(6)——分布式集群学习分享1
在使用中我们把文档存入ElasticSearch,但是如果能够了解ElasticSearch内部是如何存储的,将会对我们学习ElasticSearch有很清晰的认识.本文中的所使用的ElasticSe ...
- MySQL学习分享--Thread pool实现
基于<MySQL学习分享--Thread pool>对Thread pool架构设计的详细了解,本文主要对Thread pool的实现进行分析,并根据Mariadb和Percona提供的开 ...
- JavaScript Shell学习分享
目录 JavaScript Shell学习分享 简介 安装 使用原因 小结 JavaScript Shell学习分享 简介 JavaScript Shell是由Mozilla提供的综合JavaScri ...
- python 学习分享-paramiko模块
paramiko模块学习分享 paramiko是用python语言写的一个模块,遵循SSH2协议,支持以加密和认证的方式,进行远程服务器的连接.paramiko支持Linux, Solaris, BS ...
- 有关JSOUP学习分享(一)
其实现在用JSOUP爬虫的也不多了,但是由于最近换公司,做数据爬虫需要用到,就看了下,感觉还是挺好用的,原理什么的感觉和weblogic也差不到哪里去,废话少说,这里就简单的分享下最近接触的干货. J ...
- Swagger框架学习分享
Swagger框架学习分享 转至元数据结尾 Created and last modified by 刘新宇 大约1分钟曾经 pageId=162045803#page-metadata-start& ...
- Flink 从0到1学习—— 分享四本 Flink 国外的书和二十多篇 Paper 论文
前言 之前也分享了不少自己的文章,但是对于 Flink 来说,还是有不少新入门的朋友,这里给大家分享点 Flink 相关的资料(国外数据 pdf 和流处理相关的 Paper),期望可以帮你更好的理解 ...
- python paramiko模块学习分享
python paramiko模块学习分享 paramiko是用python语言写的一个模块,遵循SSH2协议,支持以加密和认证的方式,进行远程服务器的连接.paramiko支持Linux, Sola ...
随机推荐
- Hadoop YARN资源隔离技术
YARN对内存资源和CPU资源采用了不同的资源隔离方案.对于内存资源,它是一种限制性资源,它的量的大小直接决定应用程序的死活,因为应用程序到达内存限制,会发生OOM,就会被杀死.CPU资源一般用Cgr ...
- Codeforces 546E Soldier and Traveling(最大流)
题目大概说一张无向图,各个结点初始有ai人,现在每个人可以选择停留在原地或者移动到相邻的结点,问能否使各个结点的人数变为bi人. 如此建容量网络: 图上各个结点拆成两点i.i' 源点向i点连容量ai的 ...
- 使用expdp时遇到ORA-39002、ORA-39070错误
使用expdp时,遇到”ORA-39002.ORA-39070......”连续报错. 1. 遇到的问题 expdp yguo/dbimp@botnet schemas=yguo dumpfile= ...
- CF# Educational Codeforces Round 3 B. The Best Gift
B. The Best Gift time limit per test 2 seconds memory limit per test 256 megabytes input standard in ...
- 【Oralce】时间操作
加法 select sysdate,add_months(sysdate,12) from dual; --加1年 select sysdate,add_months(sysdate,1 ...
- css3+js打造炫酷图片展示
<!DOCTYPE html> <html onselectstart="return false"> <!-- onselectstart=&quo ...
- BZOJ3759: Hungergame 博弈论+线性基
学了新的忘了旧的,还活着干什么 题意:一些盒子,每步可选择打开盒子和取出已打开盒子的任意多石子,问先手是否必胜 搬运po姐的题解: 先手必胜的状态为:给出的数字集合存在一个异或和为零的非空子集,则先手 ...
- RSA_RSA算法原理(二)
上一次,我介绍了一些数论知识. 有了这些知识,我们就可以看懂RSA算法.这是目前地球上最重要的加密算法. 六.密钥生成的步骤 我们通过一个例子,来理解RSA算法.假设爱丽丝要与鲍勃进行加密通信,她该怎 ...
- Working with C# dictionary
Check dictionary value if it's empty dictionary.ElementAt(i).Value == DBNull.Value Check string valu ...
- win10添加打印机--无法访问指定设备,路径或文件。。
win10添加打印机无法访问指定设备,路径或文件..后来发现很多按钮点击多说无法访问指定设备,路径或文件.. 解决添加打印机问题: 在搜索栏中搜索:print (从这里添加) 彻底解决: 添加环境变量 ...