IOS-layoutSubviews方法的调用时机
前言
最近在开发项目的过程中,修改以前的布局代码,之前单独设置上、下、宽度、高度,的值是正常,但是我改成设置空间的frame之后,程序运行发生了死循环, 最后找到子控件的layoutSubviews方法中设置自身的高度,然后再父视图,我又设置了该控件的frame。
子控件的代码:

在运行之后,展示该控件时,发生了死循环, 自己对layoutSubviews的调用时机,也不是很清楚,所以这里想学习记录下layoutSubviews方法的调用时机
这里需要注意的是layoutSubviews本身不会做任何工作,它只是提供了一个调用时机,需要自己重写
layoutSubviews调用时机
- 注意: 这里需要注意的是,我们创建控件,调用控件的
init或则initWithFrame方法都是不会触发控件的layoutSubviews方法的调用的

setNeedsLayout 和 layoutIfNeeded
- 调用view的
setNeedsLayout方法时,这时候会触发该view的layoutSubviews方法的调用,这里需要是一一对应的关系,那个view调用setNeedsLayout方法就触发哪个view的layoutSubviews方法

对此官方文档有一段描述:
You should not call this method directly. If you want to force a layout update, call the
setNeedsLayoutmethod instead to do so prior to the next drawing update. If you want to update the layout of your views immediately, call thelayoutIfNeededmethod.
大概的意思如下:
您不应该直接调用此方法。如果你想强制一个布局更新,调用
setNeedsLayout方法,而不是在下一次绘图更新之前这样做。如果您想立即更新视图的布局,请调用layoutIfNeeded方法。
所以调用layoutIfNeeded方法,也会触发layoutSubviews方法的回调

addSubview
当触发addSubView时, view和子view的layoutSubviews方法会调用, 并且是先调用View的layoutSubviews方法在调用子view的, 而且就算是添加多个子view,那么view的layoutSubviews也只会调用一次, 而不是调用多次

上述情况指的是在同一个RunLoop中,也就是同一个线程中, 那么如果在不同的RunLoop(不同线程)中调用addSubview方法了, 那么都会触发多次, 输出结果如下:

注意: 如果view的size是0,那么及时调用addSubview,也不会触发大小为0的view的layoutSubviews方法(注意这是size为0.就是宽度和高度都为0,如果只有其中为0,还是会调用layoutSubviews方法的)


改变view的size大小
当我们改变view的大小的时候,会触发view的layoutSubviews方法的调用, 但是如果没有触发size的改变,只是触发了位置的改变, 是不会触发layoutSubviews的
-
修改位置

-
改变size

如果是改变子view的size,那么子view和父view的layoutSubviews方法都会调用

需要注意点
- 旋转屏幕只会调用
controller的self.view的layoutSubviews - 关于在
父view的layoutSubviews里改变子view的frame不会循环调用的问题是因为一般情况下改变子view的frame的值都是固定的,而如果每次改变的值不同,也会重复调用父view的layoutSubviews

本文解析了iOS中的layoutSubviews方法触发时机,包括setNeedsLayout和layoutIfNeeded的使用,addSubview影响,以及尺寸变化和屏幕旋转的影响。重点讲解了如何避免死循环并理解布局更新的流程。
1205

被折叠的 条评论
为什么被折叠?



