layoutSubViews()、setNeedsLayout(
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()