Masonry整体动画更新约束

前言

说到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

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

@interface TotalUpdateController ()

@property (nonatomic, strong) UIView *purpleView;

@property (nonatomic, strong) UIView *orangeView;

@property (nonatomic, assign) BOOL isExpaned;

@end

@implementation TotalUpdateController

- (void)viewDidLoad {

[super viewDidLoad];

UIView *purpleView = [[UIView alloc] init];

purpleView.backgroundColor = UIColor.purpleColor;

purpleView.layer.borderColor = UIColor.blackColor.CGColor;

purpleView.layer.borderWidth = 2;

[self.view addSubview:purpleView];

UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(onTap)

];

[purpleView addGestureRecognizer:tap];

self.purpleView = purpleView;

UIView *orangeView = UIView.new;

orangeView.backgroundColor = UIColor.orangeColor;

orangeView.layer.borderColor = UIColor.blackColor.CGColor;

orangeView.layer.borderWidth = 2;

[self.view addSubview:orangeView];

self.orangeView = orangeView;

// 这里,我们不使用updateViewConstraints方法,但是我们一样可以做到。

// 不过苹果推荐在updateViewConstraints方法中更新或者添加约束的

[self updateWithExpand:NO animated:NO];

UILabel *label = [[UILabel alloc] init];

label.numberOfLines = 0;

label.textColor = [UIColor redColor];

label.font = [UIFont systemFontOfSize:16];

label.textAlignment = NSTextAlignmentCenter;

label.text = @"点击purple部分放大,orange部分最大值250,最小值90";

[self.purpleView addSubview:label];

[label mas_makeConstraints:^(MASConstraintMaker *make) {

make.bottom.mas_equalTo(0);

make.left.right.mas_equalTo(0);

}];

}

- (void)updateWithExpand:(BOOL)isExpanded animated:(BOOL)animated {

self.isExpaned = isExpanded;

[self.purpleView mas_updateConstraints:^(MASConstraintMaker *make) {

make.left.top.mas_equalTo(20);

make.right.mas_equalTo(-20);

if (isExpanded) {

make.bottom.mas_equalTo(-20);

} else {

make.bottom.mas_equalTo(-300);

}

}];

[self.orangeView mas_updateConstraints:^(MASConstraintMaker *make) {

make.center.mas_equalTo(self.purpleView);

// 这里使用优先级处理

// 设置其最大值为250,最小值为90

if (!isExpanded) {

make.width.height.mas_equalTo(100 * 0.5).priorityLow();

} else {

make.width.height.mas_equalTo(100 * 3).priorityLow();

}

// 最大值为250

make.width.height.lessThanOrEqualTo(@250);

// 最小值为90

make.width.height.greaterThanOrEqualTo(@90);

}];

if (animated) {

[self.view setNeedsUpdateConstraints];

[self.view updateConstraintsIfNeeded];

[UIView animateWithDuration:0.5 animations:^{

[self.view layoutIfNeeded];

}];

}

}

- (void)onTap {

[self updateWithExpand:!self.isExpaned animated:YES];

}

@end

讲解

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

这里展开与收起的关键代码在这里.设置最大最小值,这样就不会超出我们预期的范围。

1

2

3

4

5

6

7

// 最大值为250

make.width.height.lessThanOrEqualTo(@250);

// 最小值为90

make.width.height.greaterThanOrEqualTo(@90);

我们设置其固定的宽高,并且设置其优先级为最低,以保证我们所设置的最大最小值始终生效。

想要更新约束时添加动画,就需要调用关键的一行代码: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];

}];

时间: 2024-10-15 09:33:38

Masonry整体动画更新约束的相关文章

Masonry 动画更新约束

前言 说到iOS自动布局,有很多的解决办法.有的人使用xib/storyboard自动布局,也有人使用frame来适配.对于前者,笔者并不喜欢,也不支持.对于后者,更是麻烦,到处计算高度.宽度等,千万大量代码的冗余,对维护和开发的效率都很低. 笔者在这里介绍纯代码自动布局的第三方库:Masonry.这个库使用率相当高,在全世界都有大量的开发者在使用,其star数量也是相当高的. 效果图 本节详解Masonry的以动画的形式更新约束的基本用法,先看看效果图: 我们这里初始按钮是一个很小的按钮,点击

Masonry remake更新约束

前言 说到iOS自动布局,有很多的解决办法.有的人使用xib/storyboard自动布局,也有人使用frame来适配.对于前者,笔者并不喜欢,也不支持.对于后者,更是麻烦,到处计算高度.宽度等,千万大量代码的冗余,对维护和开发的效率都很低. 笔者在这里介绍纯代码自动布局的第三方库:Masonry.这个库使用率相当高,在全世界都有大量的开发者在使用,其star数量也是相当高的. 效果图 本节详解Masonry的以动画的形式更新约束的基本用法,先看看效果图: 我们这里初始按钮是一个很小的按钮,点击

Xcode8更新约束

Xcode升级之后就会发现约束设置好,想更新一下约束,看看约束是不是刚刚好,习惯性的去点右下角的更新约束的结果却发现没有更新约束的这一项了,好尴尬. 后来发现原来在Xcode8的约束更新换了一个地方,并不是在原来的右下角那个地方,而是在原来的那一行的最左边,点击即可更新约束,就会看到约束加的是否正确. 附图:

更新约束动画

_isOrderOpen = !_isOrderOpen; [UIView animateWithDuration:0.5 animations:^{ if (_isOrderOpen) { _orderControlConstant.constant = 50; } else { _orderControlConstant.constant = 0; } [self.view layoutIfNeeded]; }];

关于自动布局更新约束方法的总结

1.layoutSubviews 在iOS5.1和之前的版本,此方法的缺省实现不会做任何事情(实现为空),iOS5.1之后(iOS6开始)的版本,此方法的缺省实现是使用你设置在此view上面的constraints(Autolayout)去决定subviews的position和size. UIView的子类如果需要对其subviews进行更精确的布局,则可以重写此方法.只有在autoresizing和constraint-based behaviors of subviews不能提供我们想要的

Window.requestAnimationFrame()动画更新

概述 Window.requestAnimationFrame()方法告诉浏览器你希望执行动画,并且再下一次重绘之前要求浏览器调用一个特定的函数去更新动画.该方法把一个回调函数作为参数,该回调函数会在浏览器下一次重绘之前执行. 注意:如果你想在浏览器下次重绘之前继续更新下一帧动画,那么回调函数自身必须再次调用Window.requestAnimationFrame() 当你准备更新你的动画的时候,你应该调用该方法.这会要求你的动画函数在浏览器下次重绘之前被调用.回调的频率一般是60次/秒,但通常

【iOS入门】mesonry 更新约束注意点

练习UI布局 masonry 把下划线View移动左边. 开始时对齐中间的 lable ,点击时移动到对应lable下面. 使用方法: [indicator mas_updateConstraints:^(MASConstraintMaker *make) { make.centerX.equalTo(curCurTab); }]; 直接报错: [LayoutConstraints] Unable to simultaneously satisfy constraints. Probably a

Coding源码学习第四部分(Masonry介绍与使用(三))

接上篇继续进行Masonry 的学习. (12)tableViewCell 布局 1 #import "TableViewController.h" 2 #import "TestTableViewCell.h" 3 4 @interface TableViewController ()<UITableViewDelegate, UITableViewDataSource> 5 6 @property(nonatomic, strong) UITable

Coding源码学习第四部分(Masonry介绍与使用(二))

接上篇,本篇继续对Masonry 进行学习,接上篇示例: (6)Masonry 布局实现iOS 计算器 1 - (void)exp4 { 2 WS(weakSelf); 3 // 申明区域,displayView 是显示布局,keyboardView 是键盘区域 4 UIView *displayView = [UIView new]; // 创建并添加 显示区域 5 [displayView setBackgroundColor:[UIColor blackColor]]; 6 [self.v