前言
masonry 是用于实现约束布局的三方库,一个成熟稳定的库(稳定到已经许多年不再更新了)。并且由于约束布局本身的灵活性,masonry 也就成为了 OC 开发中,除代码布局外最常用到的布局方案。
背景
masonry 的正常使用就跳过不讲,主要讲下在设置完 masonry 的约束条件后,如何及时获取到宽高的问题.
在使用 masonry 的时候,默认情况下,设置的约束并不会立即生效,也就意味着此时获取到的所有的 frame 值都为 0。
代码示意
view1 = [UIView new];
[self.view addSubview:view1];
[view1 mas_makeConstraints:^(MASConstraintMaker *make) {
make.edges.equalTo(self.view).insets(UIEdgeInsetsMake(10, 10, 10, 10));
}];
NSLog(@"%@",view1.description);
得到的结果显示frame为0:
<UIView: 0x7f9d20d0b650; frame = (0 0; 0 0); layer = <CALayer: 0x608000227900>>
约束立即生效
而在有些场景,我们需要及时的获取到此时的宽跟高,那么就需要实现设置控件的约束立即生效。 所以需要在 mas_makeConstraints 之后用它的父视图调用 layoutIfNeeded 可以使得约束立即生效:
view1 = [UIView new];
[self.view addSubview:view1];
[view1 mas_makeConstraints:^(MASConstraintMaker *make) {
make.edges.equalTo(self.view).insets(UIEdgeInsetsMake(10, 10, 10, 10));
}];
[self.view layoutIfNeeded];
NSLog(@"%@",view1.description);
得到的结果显示:
<UIView: 0x7fa8d8d05730; frame = (10 10; 394 716); layer = <CALayer: 0x60800003ca20>>
提示:layoutIfNeeded在自身也可以生效,不过可能会导致坐标不准确等后果,而用在父视图上不会发生问题。
layoutIfNeeded 是用于强制立即布局并更新视图,并遍历其 subviews 链,实现所有的内容都进行更新
关于约束更新:
约束更新内容简要写一些,不写详细代码了。
约束更新内容内容有两种方案
- 写入 mas_updateConstraints 中
- 写入 mas_remakeConstraints 中
其中的区别在于 mas_updateConstraints
只会更新单独的那条约束,而 mas_remakeConstraints
相当于移除约束后重新设置约束.
而如果需要约束的立即更新的话需要两个步骤
- updateConstraintsIfNeeded
- layoutIfNeeded
两个方法都是在父视图中使用的。layoutIfNeeded
上文已经说明过了,updateConstraintsIfNeeded
则是立即更新约束内容。且顺序必须是先调用 updateConstraintsIfNeeded
再调用 layoutIfNeeded