布局和约束相关的生命周期(layoutIfNeeded,updateConstraintsIfNeeded)
1.setNeedsLayout
作用:
标记视图的布局需要更新。它不会立即触发布局更新,而是在下一个布局周期中更新
调用时机:
当你改变了一些影响视图布局的属性(如frame、bounds等)后,需要调用此方法告诉系统该视图需要重新布局。
使用详情:
调用后,系统不会立即更新,会在下一个布局周期中调用`layoutSubviews`方法。它不会立即生效,而是等待下一个run loop。
2.layoutIfNeeded
作用:
立即触发视图的布局更新。如果视图被标记为需要布局,则立即调用`layoutSubviews`方法
调用时机:
当你需要立即更新视图的布局时调用,例如在动画块中改变约束后立即更新布局以捕获动画的起始和结束状态。
使用详情:
这个方法会强制视图立即进行布局。通常在动画中使用.动画中必须调用
layoutIfNeeded
// 改变约束constraint.constant = 100// 立即布局父视图view.layoutIfNeeded()UIView.animate(withDuration: 0.3) {// 再次改变约束constraint.constant = 200// 在动画块中再次调用,使动画生效view.layoutIfNeeded()}
3.layoutSubviews
作用:
系统调用的方法,用于重新布局子视图。你可以重写此方法来调整子视图的位置和大小(禁止手动调用)
调用时机:
1.系统在需要重新布局视图的子视图时自动调用
2.addSubview的时候。=>当添加子控件的时候,不管子控件有没有尺寸都会调用
3.当view的size发生改变的时候。=>当size改变的时候调用一次(size每次都不同,如果size相同就不会调用)
4.滑动UIScrollView的时候。
5.旋转Screen会触发父UIView上的layoutSubviews事件。注意:当view的size的值为0的时候,addSubview也不会调用layoutSubviews。当要给这个view添加子控件的时候不管他的size有没有值都会调用===>初始化,当size不为0的时候调用一次,当size为0的时候不会调用(在任何方法里面都不会调用)
使用详情:
你不能直接调用这个方法。如果需要触发布局,使用`setNeedsLayout`或`layoutIfNeeded`。如果重写该方法时,务必调用`super.layoutSubviews()`
4.setNeedsUpdateConstraints
作用:
标记视图的约束需要更新。它不会立即更新约束,而是在下一个更新周期中更新。
调用时机:
当视图的约束需要改变时调用此方法,例如需要动态改变约束条件
使用详情:
调用后,系统会在下一个布局周期中调用`updateConstraints`方法。通常与`updateConstraintsIfNeeded`配合使用
5.updateConstraintsIfNeeded
作用:
立即更新视图的约束。如果视图被标记为需要更新约束,则立即调用`updateConstraints`方法
调用时机:
当你需要立即更新约束时调用,例如在布局之前确保约束是最新的
使用详情:
这个方法会强制视图立即更新约束。通常在需要立即获取最新布局信息时使用,比如在计算布局前.
6.updateConstraints
作用:
系统调用的方法,用于更新视图的约束。你可以重写此方法来动态改变约束.(禁止手动调用)
调用时机:
系统在需要更新约束时自动调用,例如当视图被标记为需要更新约束时(通过`setNeedsUpdateConstraints`)
使用详情:
你不能直接调用这个方法。如果需要触发约束更新,使用`setNeedsUpdateConstraints`或`updateConstraintsIfNeeded`。重写该方法时,务必调用`super.updateConstraints()`,并在方法内更新约束
使用原则
最佳实践
修改约束后
myConstraint.constant = 100
myView.setNeedsLayout() // 标记布局更新
// 或立即更新:
myView.layoutIfNeeded()
动画中:必须调用
layoutIfNeeded
UIView.animate(withDuration: 0.3) {self.myConstraint.constant = 200self.view.layoutIfNeeded() // 关键!
}
避免在 layoutSubviews 中修改约束:可能导致布局循环
性能优化
批量修改后调用一次
setNeedsLayout
优先使用约束更新而非直接修改 frame
复杂布局使用
updateConstraints
集中管理约束
总结:
标记更新:
setNeedsLayout
/setNeedsUpdateConstraints
(异步)强制立即更新:
layoutIfNeeded
/updateConstraintsIfNeeded
(同步)系统回调:
layoutSubviews
/updateConstraints
(重写但不主动调用)