1、label约束:

  1)、只需约束x、y 点相关就行。宽高 长度相关不用约束,就算用boundingRectWithSize计算出来的,也可能不准。

    如:top、bottom二选一,trailing、leading二选一,或者center,宽高会自动生成。(同时约束trailing、leading的话,相当于设了宽度)

  2)、有些地方怕label过长超出,或覆盖其他控件,这时就需要约束 宽高,让其“...”。

    后续补充:还是没必要约束宽,可以让top、bottom、trailing、leading设置 lessThanOrEqualTo 属性。

         小于正常显示,大于会省略号,比起 equalTo 宽,写死的,会好用些

         比如高写死的话,会发现,字体垂直居中,这样就和左边的“标题Label”,水平不对齐了

         1)、lessThanOrEqualTo:小于或等于(注意负号)( label 有个最大宽度属性 preferredMaxLayoutWidth,有点像? )

         2)、equalTo:等价于

         3)、greaterThanOrEqualTo:大于或等于(注意负号)

  3)、垂直约束,我更喜欢用centerY。

    用top的话:1)、UI的字体大小和iOS可能会有偏差,多行label,误差就越大。而设中心点,他是中心定点,上下伸缩。

            2)、如果又有一个控件,如ImageView,跟label的Y轴中心对齐,而label,用top对齐其他且当前label.text = nil,会出错(好像此时label的center会等于top)。

2、在cell重用里刷新数据,要用更新约束:mas_updateConstraints 或 重新约束:mas_remakeConstraints。

  后续补充:3种常用

    1)、mas_makeConstraints:约束

    2)、mas_updateConstraints:更新相同的约束对象数据,如宽。

    3)、mas_remakeConstraints:重新约束所有

  再补充:也没必要一直在cell里改约束。比如,cell里经常修改一个label的约束的时候,

    1)、可以考虑多弄几个样式的label,当前不需要的label隐藏。

    2)、可以通过 安装、卸载 。在初始化的时候,定好约束优先级。

3、UIPageControl小圆点、UISwitch开关,约束 center/ top、bottom / trailing、leading 等x、y 点即可。

4、约束centerX/centerY,容易犯的错

make.centerX.mas_equalTo(10.0);
make.centerX.offset(10.0);

  语句看起来,像是给centerX = 10.0的数值,然而效果却是父视图的centerX + 10.0,

  原因,参照下面的附录,它自动默认一样的属性。应该写详细点。

make.centerX.mas_equalTo(self.view.mas_leading).offset(10.0);

  再补充:如果1个固定的控件和1个移动的控件(下划线)centerX,约束一样,如,make.centerX.mas_equalTo(固定.mas_centerX),

      接着,想通过mas_updata,更新centerX到另一个控件,会发现约束冲突,连固定的控件一起移动。

      解决,取另一个参照物。

        1)、newCenterX = 另一个控件.centerX 。

        2)、make.centerX.mas_equalTo(固定.mas_leading).offset(newCenterX)

5、属性

  1)、之前用得较多的:top、bottom、trailing、leading、center、width、height

  2)、现在开始用的 edges == top、bottom、trailing、leading。

             insets 在 边界约束好的基础上,设置与父视图的间隙,为正值!!也可以直接在edges里设置,一样。

           size == width、height。

           sizeOffset 在 size 约束好的基础上,进行增+减-。主要用于相对另一个View。

           multipliedBy 倍数,比如0.5、1.5。不局限在相同属性,也可以设置为自身 width 为 height 的3倍。

  3)、center 配合 size 不错。就像layer的 position 和 bound 。

6、父视图contentView的宽高,有时候可以不用设置,它会根据子类去约束,比如移除某个子View,自动缩小、变化。

  同时,也要注意因为父视图缺少约束,而造成的“自动变化Bug”。

7、优先级 与 动画( .priority(500) 或 UILayoutPriority 常量 )

  在同一个控件做约束,可以设置两个相同属性的约束,对其优先级进行设置,会先找优先级高的约束。

  优先级高约束有问题,会再向下寻找次之优先级的属性约束。

  默认优先级 UILayoutPriorityRequired == 1000 。

    后续补充:同一属性、同一优先级,多个约束也没问题。不过都得是greaterThanOrEqualTo、lessThanOrEqualTo的约束。

         使用参照“8、优先级与边界”。

    再补充:比如网络请求,加载到数据,给当前内容为nil的控件写入数据的时候(例如,当前 空的昵称label、空的性别图片 ,没显示出来)

        多写一行 UIView animation + layoutIfNeeded ,有意想不到的效果。  

    对 再补充 补充:使用 UIView animation + layoutIfNeeded 做动画的情况下,

            可使用 [self.animationView.layer removeAllAnimations]; 移除动画,如需可用 block 的 finished 判断是否完成动画

[UIView animateWithDuration:8.0
delay:0.0
options:UIViewAnimationOptionCurveLinear
animations:^{
// 动画
[self layoutIfNeeded];
} completion:^(BOOL finished) {
// 动画完成
[self.animationView mas_updateConstraints:^(MASConstraintMaker *make) {
make.leading.mas_equalTo(SCREEN_WIDTH);
}];
}];

    再再补充:做弹窗动画,如果初始化为约束,做动画也用 约束+ UIView animation + layoutIfNeeded,在第一次(懒)加载的时候会导致所有的控件一起动画,

         可先在初始化的时候 [self setNeedsLayout] + [self layoutIfNeeded] ,完成UI布局。

  1)、如 移除优先级高的参照物,再layout。就可以做动画。

    [view mas_makeConstraints:^(MASConstraintMaker *make) {
make.leading.equalTo(参照物1.mas_trailing).offset(20).priority(750);
make.leading.equalTo(参照物2.mas_trailing).offset(20).priority(250);
}]; [参照物1 removeFromSuperview];
[UIView animateWithDuration:1.0 animations:^{
[self.view layoutIfNeeded];
}];

  2)、或者提取出来

    2-1)、卸载掉该约束

    MASConstraint *leadingMas;

    [view mas_makeConstraints:^(MASConstraintMaker *make) {
leadingMas = make.leading.equalTo(参照物1.mas_trailing).offset(20).priority(750);
make.leading.equalTo(参照物2.mas_trailing).offset(20).priority(250);
}]; [leadingMas uninstall];
[UIView animateWithDuration:1.0 animations:^{
[self.view layoutIfNeeded];
}];

  后续补充:卸载uninstall、安装install 可以重复。只要变量没释放

    2-2)、修改约束。

    MASConstraint *widthMas;

    [view mas_makeConstraints:^(MASConstraintMaker *make) {
widthMas = make.width.equalTo(50);
}]; widthMas.equalTo(100);
[UIView animateWithDuration:1.0 animations:^{
[self.view layoutIfNeeded];
}];

  3)、也可以用 mas_updateConstraints 对同一属性进行更新

    [view mas_updateConstraints:^(MASConstraintMaker *make) {
make.width.equalTo(100);
}]; [UIView animateWithDuration:1.0 animations:^{
[self.view layoutIfNeeded];
}];

8、优先级与边界

  1)、初始化

@property (nonatomic,strong) MASConstraint *topMas;
@property (nonatomic,strong) MASConstraint *leadingMas; [self.moveView mas_makeConstraints:^(MASConstraintMaker *make) {
// 边界。不写优先级,默认优先级最高 = UILayoutPriorityRequired = 1000
make.leading.top.greaterThanOrEqualTo(self.bgView);
make.trailing.bottom.lessThanOrEqualTo(self.bgView);
// 确定宽高
make.width.mas_equalTo(50);
make.height.mas_equalTo(50);
// 确定位置。高优先级,可变动的位置。
self.topMas = make.top.equalTo(self.bgView).offset(50).priority(750);
self.leadingMas = make.leading.equalTo(self.bgView).offset(50).priority(750);
}];

  后续补充:宽高看情况判断是否需要约束。

  2)、改变位置

    2-1)、改动 make 返回的数据

self.topMas.offset(100);
self.leadingMas.offset(100);

    2-2)、直接更新约束

[self.moveView mas_updateConstraints:^(MASConstraintMaker *make) {
make.top.mas_equalTo(self.bgView).offset(100).priority(750);
make.leading.mas_equalTo(self.bgView).offset(100).priority(750);
}];

    补充,2-1)比 2-2)需要多存2个变量,且只能修改offset,无法改之前的参照物、优先级。

              但是,写法更简洁,适合改动少的。

       优先级,可以自定宏,也可以用系统给 UILayoutPriorityDefaultHigh = 750 、UILayoutPriorityDefaultLow = 250。

    再补充:边界,也可以在拖动的时候判断x、y、x+width、y+height,纯手工计算。

9、如果两个并排的lable。

  1)、在字数(宽高)可能相互挤压的时候,可以优先保护某个Label的完整性

// 水平位置,优先级高
[label1 setContentCompressionResistancePriority:UILayoutPriorityDefaultHigh forAxis:UILayoutConstraintAxisHorizontal]; // 水平位置,优先级低(会被挤压)
[label2 setContentCompressionResistancePriority:UILayoutPriorityDefaultLow forAxis:UILayoutConstraintAxisHorizontal];

  后续补充:setContentCompressionResistancePriority 为UIView的方法,设置抗压性 优先级,第二个参数可选水平、垂直方向。

       CompressionResistance 抗压越高,则越不会被挤压,如lable被挤压,会显示“...”。

       相对的,有个 setContentHuggingPriority ,拥抱优先级,没用过,应该是优先级越高,越不会被拉伸之类的把?!

  2)、字体较少的时候,较空的地方可以用 lessThanOrEqualTo 。留空。

10、一些只要约束 位置 ,自动生成长宽的控件,如label,可以重写 intrinsicContentSize ,添加内边距,增大。

- (CGSize)intrinsicContentSize
{
CGSize tempSize = [super intrinsicContentSize];
return CGSizeMake(tempSize.width + insets.left + insets.right, tempSize.height + insets.top + insets.bottom);
}

11、自动顶住 导航栏或状态栏 , tabbar或底部

// self.mas_topLayoutGuide;
// self.mas_bottomLayoutGuide; // self.mas_topLayoutGuideTop;
// self.mas_topLayoutGuideBottom; // self.mas_bottomLayoutGuideTop;
// self.mas_bottomLayoutGuideBottom; make.top.mas_equalTo(self.mas_topLayoutGuide);

12、baseLine。

不大熟悉。好像主要应用于,对齐两个View里的子Lable,从而约束到View的位置。

重写、以返回要对齐的baseView

iOS(6.0 - 9.0)

- (UIView *)viewForBaselineLayout {
return baseView;
}

iOS(9.0 - )

- (UIView *)viewForFirstBaselineLayout{
return baseView;
} - (UIView *)viewForLastBaselineLayout{
return baseView;
}

13、scrollView约束

scrollView,可视范围正常约束,如:  

[scrollView mas_makeConstraints:^(MASConstraintMaker *make) {
make.edges.mas_equalTo(self.view);
}];

contentView,约束,如下(高度可变):

[scrollView addSubview:contentView];
[contentView mas_makeConstraints:^(MASConstraintMaker *make) {
make.edges.equalTo(scrollView);
make.width.equalTo(scrollView);
make.height.greaterThanOrEqualTo(@(0.f));
}];

需要的items,添加、约束到contentView上。

后续补充:忘了写了,最后一个item的bottom要和contentView的bottom约束上,contentView才有确定的高

14、获取上面刚约束完的尺寸,来设置别的view.frame。要先layout,否则可能获取到{0, 0, 0, 0}。

[self layoutIfNeeded];

附录:

例、两个并排的按钮

//equalTo 比较 View,
//mas_equalTo 比较 数值
//如果在 redButton 里约束有用到 greenButton ,则 greenButton 在之前就要添加到和 redButton 同一父类View下。 红色的按钮(equalTo)
UIButton *redButton = [[UIButton alloc]init];
redButton.backgroundColor = [UIColor redColor];
[self.view addSubview:redButton];
[redButton mas_makeConstraints:^(MASConstraintMaker *make) {
make.height.equalTo(@100);
make.leading.equalTo(self.view).offset(10.0);
make.bottom.equalTo(self.view).offset(-10.0);
}]; 绿色的按钮(mas_equalTo)
1)、比较全的写法
UIButton *greenButton = [[UIButton alloc]init];
greenButton.backgroundColor = [UIColor greenColor];
[self.view addSubview:greenButton];
[greenButton mas_makeConstraints:^(MASConstraintMaker *make) {
make.height.mas_equalTo(100);
make.width.mas_equalTo(redButton.mas_width);
make.trailing.mas_equalTo(self.view.mas_trailing).offset(-10.0);
make.bottom.mas_equalTo(self.view.mas_bottom).offset(-10.0);
make.leading.mas_equalTo(redButton.mas_trailing).offset(10.0);
}]; 2)、如果属性是一样的,可以省略后面的属性
make.width.mas_equalTo(redButton);
make.trailing.mas_equalTo(self.view).offset(-10.0);
make.bottom.mas_equalTo(self.view).offset(-10.0); 3)、相对于(2),甚至可以写0,相对父视图。宽可不能跟着写0,宽0就0了
make.trailing.mas_equalTo(0).offset(-10.0);
make.bottom.mas_equalTo(0).offset(-10.0); 4)、相对于(3),既然都可以0,那干脆直接去掉
make.trailing.offset(-10.0);
make.bottom.offset(-10.0);

  







iOS:Masonry约束经验(19-03-21更)的更多相关文章

  1. [19/03/17-星期日] 常用类_Calendar日历类&GregorianCalendar公历日历类

    一.概念 Calendar 类是一个抽象类,为我们提供了关于日期计算的相关功能,比如:年.月.日.时.分.秒的展示和计算. GregorianCalendar 是 Calendar 的一个具体子类,提 ...

  2. 实现iOS图片等资源文件的热更新化(五): 一个简单完整的资源热更新页面

    简介 一个简单的关于页面,有一个图片,版本号,App名称等,着重演示各个系列的文章完整集成示例. 动机与意义 这是系列文章的最后一篇.今天抽空写下,收下尾.文章本身会在第四篇的基础上,简单扩充下代码, ...

  3. deepin 15.11 升级docker-ce 18.01到19.03.1,升级docker compose 1.23到1.24.1

    1.升级docker compose ,docker官方安装方法 $ sudo curl -L "https://github.com/docker/compose/releases/dow ...

  4. [RHEL8]安装Docker Problem: package docker-ce-3:19.03.6-3.el7.x86_64 requires containerd.io

    系统环境 # cat /etc/redhat-release Red Hat Enterprise Linux release 8.0 (Ootpa) 安装依赖 # yum install -y yu ...

  5. 实现iOS图片等资源文件的热更新化(三):动态的资源文件夹

    简介 此文,将尝试动态从某个不确定的文件夹中加载资源文件.文章,会继续完善自定义的 imageNamed 函数,并为下一篇文章铺垫. 这么做的意义 正如我们经常所说的那样,大多数情景知道做事的意义往往 ...

  6. 实现iOS图片等资源文件的热更新化(零): 序

    必要的序 以后在写系列文章,准备把基本的规划和动机等,单独作为一个小的序言部分给独立出来.序言部分,可以较为完整地交待系列文章的写作动机,所展示的编码技术可能的应用场景等.个人,我还是比较看重文章或者 ...

  7. IOS 杂笔-19(属性与变量的优缺点)

    IOS 杂笔-19(属性与变量的优缺点) 在前面的文章中我介绍了属性与变量的区别.这篇博客我将会简单介绍一下属性与变量的优缺点. 变量 优点: 访问速度快 缺点: 使用不灵活 属性 缺点: 耗时 优点 ...

  8. http://www.cnblogs.com/wzh206/archive/2010/03/21/1691112.html

    http://www.cnblogs.com/wzh206/archive/2010/03/21/1691112.html

  9. 编写高质量代码改善C#程序的157个建议——建议19:使用更有效的对象和集合初始化

    建议19:使用更有效的对象和集合初始化 依赖于属性和FCL 3.5之后的语法规则,现在我们有了更加简洁有效的对象和集合初始化机制:对象和集合初始化设定项. 对象初始化: class Person { ...

随机推荐

  1. 安装使用jupyter

    介绍 jupyter是IPython剥离出来成为一个语言无关的独立软件包. jupyter已经支持50多种语言的内核,包括Lisp.R.F#.Perl.Ruby.Scala等.事实上即使IPython ...

  2. Android GridView异步加载图片和加载大量图片时出现Out Of Memory问题

    我们在使用GridView或者ListView时,通常会遇到两个棘手的问题: 1.每个Item获取的数据所用的时间太长会导致程序长时间黑屏,更甚会导致程序ANR,也就是Application No R ...

  3. unity对象物体闪烁

    Material mat; // float a=0; //控制闪烁速度 float speed=0.6f; float b=1; Update(){ if(a>0.3f){ b=1; } if ...

  4. malloc()函数,calloc()函数,realloc()函数,free()函数

    malloc()函数 头文件:#include <stdlib.h> malloc() 函数用来动态地分配内存空间,其原型为:void* malloc (size_t size); [参数 ...

  5. C#模拟HTTP POST 请求

    GET请求: /// <summary> /// 获取accessToken /// </summary> /// <param name="corpid&qu ...

  6. MSSQL->serverlink[Oracle]

    需求描述:     SQL Server数据库连接Oracle数据库   条件准备:     SQL Server数据库,SQL Server 2008R2     Oracle数据库,Oracle ...

  7. 关于asp.net MVC3 ----@Html.Partial,@Html.Action,@Html.RenderPartial,@Html.RenderAction

    1.带有Render的方法返回值是void,在方法内部进行输出:不带的返回值类型为MvcHtmlString,所以只能这样使用:@Html.Partial 对应 @{Html.RenderPartia ...

  8. 省钱小贴士(ECS):教你如何每年省出8w+ 块

    随着用户越来越多地使用阿里云的ECS服务,如何用最小的成本来保有ECS,成为用户越来越重要的关注点. 变更点 为了更好的服务客户,ECS团队调整了系统盘的最小容量限制 linux系统 core os调 ...

  9. 第六次作业——Excel制作工资表

  10. 乘风破浪:LeetCode真题_002_Add Two Numbers

    乘风破浪:LeetCode真题_002_Add Two Numbers 一.前言     这次的题目是关于链表方面的题目,把两个链表对应节点相加,还要保证进位,每个节点都必须是十进制的0~9.因此主要 ...