setNeedsLayout 和layoutIfNeeded有啥区别?

3,463 阅读1分钟

应用程序启动后会开启一个runloop,它主要用来处理事件和基于视图的页面更新。事件处理完成后会返回到runloop,这一刻成为视图更新周期。

setNeedsLayout:当事件正在处理时,视图更新的操作不会立即执行,等待下一个更新周期更新视图(即异步执行)。需要注意:当我们修改frame或者约束时,系统会自动标记布局需要重新计算。它会触发layoutsubview方法。

layoutIfNeeded:强制视图立即更新其布局,即同步执行。当使用Auto Layout时,布局引擎根据约束的变化更新视图的位置。该方法的接收者将作为根视图,布局时也将从视图树的根视图开始。如果没有待处理的布局更新,则此方法将直接退出,而不会修改布局,或调用任何与布局有关的方法。

动画:点击按钮:2秒钟view的高度慢慢从20到100.

- (void)viewDidLoad {
  [self.view addSubview:self.blueView];
  [self.blueView mas_makeConstraints:^(MASConstraintMaker *make) {
    make.left.mas_equalTo(30.);
    make.right.mas_equalTo(-30.);
    make.top.mas_equalTo(100);
    make.height.mas_equalTo(20);
  }];
 }
  
  - (void)viewDidLayoutSubviews
{
  [super viewDidLayoutSubviews];
  NSLog(@"%s",__func__);
  }
  
  
- (void)jumpToLogin:(UIButton*)btn {
  [self.view layoutIfNeeded];//让之前没有更新的强制更新。
  [self.blueView mas_updateConstraints:^(MASConstraintMaker *make) {
    make.height.mas_equalTo(100);
  }];
  
  [UIView animateWithDuration:1 animations:^{
    [self.view layoutIfNeeded];
    //如果这里用setNeedsLayout的话,是没有动画的。因为他只是标记后就返回了。
  }];
}

参考:setNeedsLayout vs layoutIfNeeded Explained

setNeedsLayout VS layoutIfNeeded中文