iOS masonry 库约束立即生效跟约束更新

1,583 阅读2分钟

前言

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 链,实现所有的内容都进行更新

关于约束更新:

约束更新内容简要写一些,不写详细代码了。

约束更新内容内容有两种方案

  1. 写入 mas_updateConstraints 中
  2. 写入 mas_remakeConstraints 中

其中的区别在于 mas_updateConstraints 只会更新单独的那条约束,而 mas_remakeConstraints 相当于移除约束后重新设置约束.

而如果需要约束的立即更新的话需要两个步骤

  1. updateConstraintsIfNeeded
  2. layoutIfNeeded

两个方法都是在父视图中使用的。layoutIfNeeded 上文已经说明过了,updateConstraintsIfNeeded 则是立即更新约束内容。且顺序必须是先调用 updateConstraintsIfNeeded 再调用 layoutIfNeeded