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. EasyNetQ简单使用

    class Program { static void Main(string[] args) { //打开消息确认机制 using (var bus = RabbitHutch.CreateBus( ...

  2. 008Spring & JPA & Hibernate & MySQL

    01下载免安装版MySQL 02安装MySQL a)将MySQL压缩包解压到合适的位置,以C:\programmer\Tools\mysql-5.7.20-winx64路径为例: b)新建系统变量,变 ...

  3. 【javascript】javascript设计模式之工厂模式

    1.要解决的问题 2.如何实现 3.与构造函数的区别 4.总结 1.要解决的问题 工厂模式通常用于重复创建相似对象,提供动态创建对象的接口. 2.工厂模式最为设计模式中构造模式之一,通常在类或类的静态 ...

  4. Ubuntu 安装 PhpMyAdmin 图文教程

    Ubuntu 安装 PhpMyAdmin 管理 MySQL 数据库 PhpMyAdmin 是一个用 PHP 编写的软件工具,可以通过 web方式控制和操作 MySQL 数据库.通过 phpMyAdmi ...

  5. Monte Carlo与TD算法

    RL 博客:http://blog.sciencenet.cn/home.php?mod=space&uid=3189881&do=blog&view=me&from= ...

  6. react native学习资料

    一:基础学习: react-native中文文档(react native中文网,人工翻译,官网完全同步)http://react-native.cn/docs/getting-started.htm ...

  7. java笔记--关于多线程状态的理解和应用

    关于多线程的状态 --如果朋友您想转载本文章请注明转载地址"http://www.cnblogs.com/XHJT/p/3890266.html  "谢谢-- 线程共有6种状态:1 ...

  8. 微软最新设计Fluent Design System初体验

    微软最新设计Fluent Design System初体验 本文图片不全!建议移步知乎专栏查看!!! https://zhuanlan.zhihu.com/p/30582886 原创 2017-11- ...

  9. Mysql进阶-day3

    多实例介绍: mysql多实例就是一台服务器开启多个不同的服务端口(3306,3307),运行多个MySQL服务进程,这些服务进程通过不同的socket监听不同的服务端口来提供各自的服务端口. 这些m ...

  10. TCP/UDP调试器 SocketToolV4.1

    TCP/UDP Socket调试工具提供了TCP Server,TCP Client,UDP Server,UDP Client,UDP Group 五种Socket调试方案.SocketTool V ...