【问题标题】:UIView/CALayer: Transform triggers layoutSubviews in superviewUIView/CALayer:Transform触发superview中的layoutSubviews
【发布时间】:2014-08-29 06:01:15
【问题描述】:

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

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

  • 框架
  • 界限

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

  • 变换
  • layer.transform

这些属性仅在自身中触发布局

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

  • 居中
  • layer.anchorPoint
  • 层.位置
  • 阿尔法

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

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


我想知道:

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

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

【问题讨论】:

  • UIScrollView 的滚动也会触发重新布局它的所有子视图。您可以覆盖 [UIScrollView layoutSubviews] 在大多数子类中什么都不做。
  • 是的,当滚动视图滚动时,它会在视图上更改bounds,这样会触发layoutSubviews
  • UIScrollView 为其 layoutSubviews 实现中的所有子视图调用 setNeedsLayout
  • 不,我不这么认为:gist.github.com/hfossli/f8c4947d3475615cd10fd6da954e4823 此外,它超出了这个问题的范围。我更想知道为什么 super 和 self 被称为 IMO过度

标签: ios uiview layoutsubviews viewdidlayoutsubviews


【解决方案1】:

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

第 1 部分

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

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

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

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

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

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

第 2 部分

嗨,哈佛,

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

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

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

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

有什么想法吗?

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

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

【讨论】:

猜你喜欢
  • 1970-01-01
  • 2021-07-29
  • 2011-02-28
  • 1970-01-01
  • 2011-11-26
  • 2013-04-09
  • 1970-01-01
  • 2018-01-10
  • 1970-01-01
相关资源
最近更新 更多