layoutSubviews触发时机解析

本文约800字,将会讲述个人对LayoutSubviews的一些更加精简的总结

!!!原创文章,转载请注明来源: pany.fun

本文的相关测试demo: layoutSubDemo

测试环境:Xcode9.2、iPhone7模拟器、iOS11.2

#前言

关于layoutSubviews什么时候触发的问题,其实网上已经有很多同学总结过啦。但是每个人的总结都大同小异,列了七八条,不是那么容易记住的。本文将在前人的基础上上进一步耕耘,进行部分解析和总结。

首先我们先来大致看看layoutSubviews。

顾名思义,它应该是用来处理布局的,而且是处理子视图的布局(这个点是很重要的)。也就是说,在某些情况下,view会在可能需要修改子视图的布局的时候触发layoutSubviews。

#普通视图的layoutSubviews的触发时机

先放结论:

· 当size发生变化的时候,会先触发父视图的layoutSubviews,再触发自己的layoutSubviews。修改origin无任何调用。

具体的来说,除了addSubview以及setNeedLayout这种特殊情况外,layoutSubviews的触发时机只有一种,就是在size发生变化的时候,我看到很多博客把它描述为frame变化,其实是不准确的。网上很多人总结的一些点,其实归根结底,也就是这一点。

但是从更加清晰的角度来说,这一条是需要拆分成 父视图的 与 自己的 两部分来理解的。

修改自己的size调用自己的layoutSubViews很好理解,因为大小变了,可能要重新布局子视图。

修改自己的origin不会调用自己的layoutSubViews也是比较好理解的,因为子视图是在自己的坐标系内布局的,自己的坐标系并没有变。

修改自己的size调用父视图的layoutSubviews 以及 修改自己的origin不会调用父视图的layoutSubviews都不太好理解,暂时没有找到相关描述与解释。🤣

#UIScrollView类型视图的layoutSubviews的触发时机

UIScrollView与普通的视图不一样的点在于,UIScrollView的contentSize和视图本身的size是可以不相等的。这使得在layoutSubviews触发方面它也有一些普通视图之外的特性。

· 当scrollView的offset发生变化时,scrollview会触发自己layoutSubviews。

注意:修改contentSize没有任何触发

这也给我们实现某些特殊需求提供了新思路。

#测试过程了解一下

本文的相关测试demo: layoutSubDemo

视图结构上,有 viewA 和 viewB, viewA 是 viewB的父视图。为了方便知道layoutSubviews的触发,我们使用了自己的view类,继承自UIView,并重写了layoutSubviews。

然后增加了一个viewC,继承自一个UIScrollView的子类,用来观察滚动对layoutSubviews的触发问题。

其它的就比较简单了,改改size,看看打印,改改origin,看看打印。相关细节可以在代码中去了解。

创作不易,转载请注明来源!pany.fun
本文链接:http://pany.fun/post/layoutsubviews/