前言

说到iOS自动布局,有很多的解决办法。有的人使用xib/storyboard自动布局,也有人使用frame来适配。对于前者,笔者并不喜欢,也不支持。对于后者,更是麻烦,到处计算高度、宽度等,千万大量代码的冗余,对维护和开发的效率都很低。

笔者在这里介绍纯代码自动布局的第三方库:Masonry。这个库使用率相当高,在全世界都有大量的开发者在使用,其star数量也是相当高的。

效果图

本节详解Masonry的以动画的形式更新约束的基本用法,先看看效果图:

我们这里初始按钮是一个很小的按钮,点击就不断放大,最大就放大到全屏幕。

核心代码

看下代码:

 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
 
@interface RemakeContraintsController ()
 
@property (nonatomic, strong) UIButton *growingButton;
@property (nonatomic, assign) BOOL isExpanded;
 
@end
 
@implementation RemakeContraintsController
 
- (void)viewDidLoad {
  [super viewDidLoad];
  
  self.growingButton = [UIButton buttonWithType:UIButtonTypeSystem];
  [self.growingButton setTitle:@"点我展开" forState:UIControlStateNormal];
  self.growingButton.layer.borderColor = UIColor.greenColor.CGColor;
  self.growingButton.layer.borderWidth = 3;
  self.growingButton.backgroundColor = [UIColor redColor];
  [self.growingButton addTarget:self action:@selector(onGrowButtonTaped:) forControlEvents:UIControlEventTouchUpInside];
  [self.view addSubview:self.growingButton];
  self.isExpanded = NO;
}
 
- (void)updateViewConstraints {
  // 这里使用update也是一样的。
  // remake会将之前的全部移除,然后重新添加
  [self.growingButton mas_remakeConstraints:^(MASConstraintMaker *make) {
    make.top.mas_equalTo(0);
    make.left.right.mas_equalTo(0);
    if (self.isExpanded) {
      make.bottom.mas_equalTo(0);
    } else {
      make.bottom.mas_equalTo(-350);
    }
  }];
  
  [super updateViewConstraints];
}
 
- (void)onGrowButtonTaped:(UIButton *)sender {
  self.isExpanded = !self.isExpanded;
  if (!self.isExpanded) {
    [self.growingButton setTitle:@"点我展开" forState:UIControlStateNormal];
  } else {
    [self.growingButton setTitle:@"点我收起" forState:UIControlStateNormal];
  }
  
  // 告诉self.view约束需要更新
  [self.view setNeedsUpdateConstraints];
  // 调用此方法告诉self.view检测是否需要更新约束,若需要则更新,下面添加动画效果才起作用
  [self.view updateConstraintsIfNeeded];
  
  [UIView animateWithDuration:0.3 animations:^{
    [self.view layoutIfNeeded];
  }];
}
 
@end
 

讲解

移除之前的所有约束,然后添加新约束的方法是:mas_remakeConstraints

这里展开与收起的关键代码在这里:

 
1
2
3
4
5
6
7
 
if (self.isExpanded) {
  make.bottom.mas_equalTo(0);
} else {
  make.bottom.mas_equalTo(-350);
}
 

想要更新约束时添加动画,就需要调用关键的一行代码:setNeedsUpdateConstraints,这是选择对应的视图中的约束需要更新。

对于updateConstraintsIfNeeded这个方法并不是必须的,但是有时候不调用就无法起到我们的效果。但是,官方都是这么写的,从约束的更新原理上讲,这应该写上。我们要使约束立即生效,就必须调用layoutIfNeeded此方法。看下面的方法,就是动画更新约束的核心代码:

 
1
2
3
4
5
6
7
8
9
10
 
// 告诉self.view约束需要更新
[self.view setNeedsUpdateConstraints];
// 调用此方法告诉self.view检测是否需要更新约束,若需要则更新,下面添加动画效果才起作用
[self.view updateConstraintsIfNeeded];
 
[UIView animateWithDuration:0.3 animations:^{
  [self.view layoutIfNeeded];
}];
 

Masonry remake更新约束的更多相关文章

  1. Masonry 动画更新约束

    前言 说到iOS自动布局,有很多的解决办法.有的人使用xib/storyboard自动布局,也有人使用frame来适配.对于前者,笔者并不喜欢,也不支持.对于后者,更是麻烦,到处计算高度.宽度等,千万 ...

  2. Masonry整体动画更新约束

    前言 说到iOS自动布局,有很多的解决办法.有的人使用xib/storyboard自动布局,也有人使用frame来适配.对于前者,笔者并不喜欢,也不支持.对于后者,更是麻烦,到处计算高度.宽度等,千万 ...

  3. snapkit更新约束崩溃的问题

    最近在使用snapkit布局时,竟然发现更新约束会导致崩溃,为什么这样呢? checkButton.snp.makeConstraints { (make) in make.left.top.equa ...

  4. Xcode8更新约束

    Xcode升级之后就会发现约束设置好,想更新一下约束,看看约束是不是刚刚好,习惯性的去点右下角的更新约束的结果却发现没有更新约束的这一项了,好尴尬. 后来发现原来在Xcode8的约束更新换了一个地方, ...

  5. Masonry控制台打印约束冲突问题解决

    不知道你是不是视图的布局也是用的第三方Masonry,在使用中是不是也遇到了控制台约束冲突的警告打印,看下图: 从输出的信息可以知道,有的控件的约束明显重复了设置,所以指出了是哪个控件,重复设置了哪些 ...

  6. Masonry第三方代码约束

    #import "RootViewController.h" #import "Masonry.h" @interface RootViewController ...

  7. 使用masonry手写约束

    在iOS开发过程中,手写contraints是非常痛苦的一件事情,往往那么一丢丢功能要写大量的代码,非常容易发生错误,并且非常不方便调试.所以只有在不得以的情况下才采用手工方式写contraints, ...

  8. ios 更新约束

    [view setNeedsUpdateConstraints];    [view updateConstraintsIfNeeded];    [view setNeedsLayout];    ...

  9. IOS开发基础知识碎片-导航

    1:IOS开发基础知识--碎片1 a:NSString与NSInteger的互换 b:Objective-c中集合里面不能存放基础类型,比如int string float等,只能把它们转化成对象才可 ...

随机推荐

  1. 【DFS+剪枝】Square

    https://www.bnuoj.com/v3/contest_show.php?cid=9154#problem/J [题意] 给定n个木棍,问这些木棍能否围成一个正方形 [Accepted] # ...

  2. TOYS(poj 2318)

    题意:就是给了m个点,落在n+1个区域中,问各个区域有多少个点. /* 对于每个玩具,二分其所在的区间,然后用叉积判断. 但是我觉得枚举好像时间复杂度也可以. */ #include<cstdi ...

  3. Java有几种线程池?

    Java通过Executors提供四种线程池,分别为:newCachedThreadPool创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程newFixed ...

  4. Codeforces Round #533 (Div. 2) E 最大独立集

    知识点 最大独立集(set) = 补图的最大团(clique ) 最小顶点覆盖 + 最大独立集 = V E. Helping Hiasat time limit per test 2 seconds ...

  5. POJ 2104 K-th Number【整体二分 + 树状数组】

    本来只是想学一下CDQ,还是先把整体二分搞懂一点. 这题窝几个月前分别用划分树,树套树,主席树和挑战上介绍的分桶法实现了一发(然而现在都忘得差不多了) 最快的是划分树,其次是主席树,然后是树套树,还有 ...

  6. zoj4028 LIS

    差分约束瞎搞一下,话说这个数据不知道怎么回事,我的图按道理而言最多只有4n条边,开5n还不够??必须6n?? 约束条件首先根据f函数可建立两点之间的约束,不妨设d[i]为i到0的距离,则对于f[i] ...

  7. Java面试题总结之Java基础(三)

    1.JAVA 语言如何进行异常处理,关键字:throws,throw,try,catch,finally分别代表什么意义?在try 块中可以抛出异常吗? 答:Java 通过面向对象的方法进行异常处理, ...

  8. eclipse导入maven工程步骤

    转自:http://jingyan.baidu.com/article/cbf0e500a6e3252eaa2893c1.html 感谢作者 步骤一 : 选择 “Import”操作 有两个途径可以选择 ...

  9. CSS浮动通俗讲解

    首先要知道,div是块级元素,在页面中独占一行,自上而下排列,也就是传说中的流.如下图: 可以看出,即使div1的宽度很小,页面中一行可以容下div1和div2,div2也不会排在div1后边,因为d ...

  10. BZOJ 1055 HAOI2008 玩具取名 动态规划

    题目大意:给定一个由'W','I','N','G'构成的字符串.给定一些规则.这些规则能够将两个字符合成为一个,比如"II"能够合成为'W',"WW"能够合成为 ...