UIView / CALayer:转换在superview中触发layoutSubviews

时间:2014-07-08 13:15:58

标签: ios uiview layoutsubviews viewdidlayoutsubviews

更改UIView的某些属性时,它会在 superview 中触发layoutSubviews。我在文档中找不到任何关于此的陈述。

这些属性会在superview和self

中触发布局
  • 边界

这些属性仅在superview中触发布局

  • 变换
  • layer.transform

这些属性仅触发自我布局

这些属性不会触发任何布局

  • 中心
  • layer.anchorPoint
  • layer.position
  • 阿尔法

我发现转换触发布局并且位置和anchorPoint没有触发布局非常混乱。

示例代码https://github.com/hfossli/LayoutSubviewsInconsistency


我想知道:

  • 为什么我会看到这种行为
  • 如果这确实是不一致的,或者我误解了一些核心概念
  • 每次我改变转换时如何避免superview to layoutSubviews

我在文档和头文件中找不到任何相关内容。使用UIDynamics或类似产品时,问题非常明显。

1 个答案:

答案 0 :(得分:28)

Apple通过TSI回答我(我个人认为这是垃圾):

第1部分

  

为什么我会看到这种行为?   这是不一致还是我误解了一些核心概念?

只要系统感觉某些内容发生变化,需要视图重新计算其子视图的帧,就会标记一个视图以进行布局。这可能比您期望的更频繁地发生,并且恰好在系统选择标记视图时,因为要求布局是实现细节。

  

为什么它会向上级联视图层次结构?

通常,更改视图(或图层)的几何属性将在视图层次结构中触发一系列布局失效,因为父视图可能具有涉及已修改子项的自动布局约束。请注意,无论您是否已明确启用自动布局,它都会以某种形式激活。

  

每次我改变变换时,如何避免对layoutSubviews进行superview观察?

无法绕过此行为。这是UIKit内部簿记的一部分,是保持视图层次一致所必需的。

第2部分

嗨Håvard,

  

但如果这是真的,我真的不明白为什么会这样   不适用于'layer.anchorPoint'和'center'/'layer.position'。

在这种情况下,我们可能会更加保守。除非涉及自动布局,否则父视图不需要关心其子项的位置。如果涉及自动布局,则需要直接修改约束以产生持久的位置调整。

  

此变换触发layoutSubviews,再次向上级联。

我的理解是,对转换的更改只会使视图的直接父级的布局无效(除非您对已更改的视图有设置约束,否则它会变得更复杂)。此外,布局失效是批处理的,因此每个事务(帧)只应调用父级布局子视图的方法一次。不过,我可以理解,如果您的布局逻辑很复杂,这可能会导致性能问题。

  

有什么想法吗?

将您的单元格内容包装在中间视图中。修改此中间视图的变换时,只应该使单元格的布局无效,因此不会调用昂贵的布局方法。

如果这不起作用,请创建一些机制,以便在实际(或不)必须执行工作时向您的昂贵布局方法发出信号。当您对变换进行的唯一更改时,这可能是您设置的属性。