应用程序启动后会开启一个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的话,是没有动画的。因为他只是标记后就返回了。
}];
}