28

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

这些属性在 superview 和 self 中触发布局

  • 框架
  • 界限

这些属性仅在超级视图中触发布局

  • 转换
  • 层变换

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

  • 没有任何

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

  • 中央
  • layer.anchorPoint
  • 层位
  • α

我发现 transform 会触发布局而 position 和 anchorPoint 不会,这很令人困惑。

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


我想知道:

  • 为什么我会看到这种行为
  • 如果这真的是不一致的,或者我误解了一些核心概念
  • 每次我更改转换时如何避免超级视图到 layoutSubviews

我在文档和头文件中找不到任何关于此的内容。当使用 UIDynamics 或类似的时候,这个问题很严重。

4

1 回答 1

31

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

第1部分

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

每当系统感觉发生了变化,需要视图重新计算其子视图的框架时,视图就会被标记为布局。这可能比您预期的更频繁地发生,并且恰好在系统选择将视图标记为需要布局是实现细节时发生。

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

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

每次更改转换时,如何避免将超级视图转换为 layoutSubviews?

没有办法绕过这种行为。它是 UIKit 内部簿记的一部分,需要保持视图层次结构一致。

第2部分

嗨,哈佛,

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

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

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

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

有任何想法吗?

将单元格内容包装在中间视图中。当你修改这个中间视图的变换时,只有单元格的布局应该是无效的,所以你昂贵的布局方法不会被调用。

如果这不起作用,请创建一些机制来向您的昂贵布局方法发出信号,因为它实际上需要(或不需要)工作。当您所做的唯一更改是对转换时,这可能是您设置的属性。

于 2014-07-10T09:34:15.480 回答