layoutSubviews何时被调用?
我有一个自定义视图,在animation过程中不会获取layoutSubview消息。 
 我有一个观点,填补了屏幕。 如果我更改导航栏的高度,它将在界面生成器中正确resize的屏幕底部有一个自定义子视图。  layoutSubviews在创build视图时被调用,但不会再次。 我的子视图是正确的布局。 如果我closures了通话状态栏,那么即使主视图执行了其resize的animation,子视图的layoutSubviews也不会被调用。 
  layoutSubviews在什么情况下实际调用? 
 我有autoresizesSubviews设置为NO为我的自定义视图。 在界面生成器中,我有顶部和底部支柱和垂直箭头集。 
我有一个类似的问题,但不满意的答案(或任何我可以在网上find),所以我尝试了在实践中,这就是我得到的:
-   init不会导致layoutSubviews被调用(duh)
-   addSubview:使layoutSubviews在被添加的视图,被添加到的视图(目标视图)和目标的所有子视图上被调用
-  仅当帧的大小参数不同时, setFrame智能地在视图上调用layoutSubviews来设置其框架
-  滚动UIScrollView会导致layoutSubviews在scrollView和它的超级视图上被调用
-  旋转设备只调用父视图上的layoutSubview(响应的viewControllers主视图)
-  调整视图的大小将调用layoutSubviews
我的结果 – http://blog.logichigh.com/2011/03/16/when-does-layoutsubviews-get-called/
 build立在@BadPirate之前的答案上,我进一步尝试了一些,并提出了一些澄清/更正。 我发现layoutSubviews:只会在layoutSubviews:情况下被调用: 
- 它自己的界限 (不是框架)改变了。
- 其中一个直接子视图的边界改变了。
- 子视图被添加到视图或从视图中删除。
一些相关的细节:
-  只有在新值不同的情况下,边界被认为才会被改变, 包括不同的原点 。 特别注意这就是为什么layoutSubviews:在UIScrollView滚动的时候被调用,因为它通过改变边界的原点来执行滚动。
- 改变框架只会改变边界,如果大小已经改变,这是唯一传播到边界属性。
-  尚未处于视图层次结构中的视图边界的更改将导致调用layoutSubviews:视图最终被添加到视图层次结构中 。
-  为了完整起见,这些触发器不直接调用layoutSubviews,而是调用setNeedsLayout来设置/引发一个标志。 运行循环的每个迭代中,对于视图层次结构中的所有视图,都将检查此标志。 对于发现标志的每个视图,调用layoutSubviews:并重置该标志。 更高级别的视图将首先被检查/调用。
BadPirate的答案中的一些要点只是部分正确:
- 
对于 addSubView点addSubview使layoutSubviews在被添加的视图,被添加到的视图(目标视图)和目标的所有子视图上被调用。这取决于视图的(目标视图)自动resize掩码。 如果它具有自动调整掩码ON,则将在每个 addSubview上调用layoutSubview。 如果它没有自动resize的掩码,那么只有当视图的(目标视图)帧大小发生变化时才会调用layoutSubview。例如:如果以编程方式创build了UIView(默认情况下它没有自动resize的掩码),那么只有在UIView框架没有在每个 addSubview上更改时才会调用LayoutSubview。正是通过这种技术,应用程序的性能也增加了。 
- 
对于设备旋转点 旋转设备只调用父视图上的layoutSubview(响应的viewController的主视图) 只有当你的VC在VC层次结构(根目录 window.rootViewController)时,这才是真的,这是最常见的情况。 在iOS 5中,如果你创build了一个VC,但是它没有被添加到任何其他的VC中,那么这个VC在设备旋转时不会被注意到。 因此,通过调用layoutSubviews,它的视图不会被注意到。
我将解决scheme跟踪到Interface Builder的坚持,弹簧不能在具有模拟屏幕元素(状态栏等)的视图上更改。 由于主要观点的弹簧是closures的,所以这个观点不能改变尺寸,因此在出现呼叫栏时整体向下滚动。
closures模拟function,然后调整视图大小并正确设置弹簧,导致animation发生,并调用我的方法。
在debugging时遇到的一个额外的问题是,当通过菜单切换通话状态时,模拟器退出应用程序。 退出应用程序=没有debugging器。
 调用[self.view setNeedsLayout]; 在viewController使它调用viewDidLayoutSubviews 
在视图中发生以下任何事件时,可能会发生布局更改:
一个。 视图边界矩形的大小发生变化。
湾 发生界面方向更改,通常会触发根视图边界矩形中的更改。
C。 与视图图层相关联的核心animation子图层组发生更改,并且需要布局。
d。 您的应用程序通过调用视图的setNeedsLayout或layoutIfNeeded方法来强制执行布局。
即 您的应用程序通过调用视图底层对象的setNeedsLayout方法来强制布局。

你有没有看过layoutIfNeeded?
文档片段如下。 如果在animation期间显式调用此方法,animation是否工作?
layoutIfNeeded根据需要放置子视图。
 - (void)layoutIfNeeded 
讨论使用此方法在绘制之前强制子视图的布局。
可用性在iPhone OS 2.0及更高版本中可用。
将OpenGL应用程序从SDK 3迁移到4时,layoutSubviews不再被调用。 经过大量的反复试验后,我终于打开了MainWindow.xib,select了Window对象,在检查器中select了Window Attributes选项卡(最左边)并选中“Visible at launch”。 看起来,在SDK 3中它仍然用于导致layoutSubViews调用,但不是在4中。
6个小时的挫折结束了。
这个难题的另一个部分是窗户必须是关键的:
 [window makeKeyAndVisible]; 
其他子视图不会自动resize。
  layoutSubviews永远不会被调用的另一个比较晦涩但非常重要的情况是: 
 class View: UIView { override class var layerClass: AnyClass { return Layer.self } class Layer: CALayer { override func layoutSublayers() { // if we don't call super.layoutSublayers() } } override func layoutSubviews() { // this never gets called by the OS! print(#function) } }