layoutSubViews()、setNeedsLayout()、layoutIfNeeded() 的用法

layoutSubViews
默认没有做任何事情,需要子类进行重写 。 系统在很多时候会去调用这个方法:

1.初始化不会触发layoutSubviews,但是如果设置了不为CGRectZero的frame的时候就会触发。
2.addSubview会触发layoutSubviews
3.设置view的Frame会触发layoutSubviews,当然前提是frame的值设置前后发生了变化
4.滚动一个UIScrollView会触发layoutSubviews
5.旋转Screen会触发父UIView上的layoutSubviews事件
6.改变一个UIView大小的时候也会触发父UIView上的layoutSubviews事件

setNeedsLayout
标记为需要重新布局,不立即刷新,但layoutSubviews一定会被调用
配合layoutIfNeeded立即更新

layoutIfNeeded
如果有需要刷新的标记,立即调用layoutSubviews进行布局

如果要立即刷新,要先调用[view setNeedsLayout],把标记设为需要布局,然后马上调用[view layoutIfNeeded],实现布局

在视图第一次显示之前,标记总是“需要刷新”的,可以直接调用[view layoutIfNeeded]

[UIView animateWithDuration:1 animations:^{
    _labelBottomCons.constant = 200;
 }];

如果我们用上面的代码实现一个动画,会发现根本没有动画。
因为_labelBottomCons.constant = 200;只是执行了setNeedsLayout标记了需要重新布局,但是没有立即执行。所以我们需要在动画中调用这个方法layoutIfNeeded
所以应该这样写

    _labelBottomCons.constant = 200;
    [UIView animateWithDuration:1 animations:^{
        [self.view layoutIfNeeded];
    }];

所以上面不管写多少约束的改变,只需要在动画里动用 一次self.view.layoutIfNeeded() ,所有的都会已动画的方式 。如果一些变化不想动画 。在动画前执行self.view.layoutIfNeeded()

推荐阅读更多精彩内容