UIView/CALayer:转换触发超级视图中的layoutSubviews [英] UIView/CALayer: Transform triggers layoutSubviews in superview

查看:113
本文介绍了UIView/CALayer:转换触发超级视图中的layoutSubviews的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

更改UIView的某些属性时,将触发 superview 中的layoutSubviews.我在文档中找不到关于此的任何声明.

When changing some of the properties for UIView it triggers layoutSubviews in the superview. I can not find any statements about this in the docs.

这些属性会触发超级视图和自我中的布局

These properties triggers layout in superview and self

  • 框架
  • 界线

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

These properties triggers layout in superview only

  • 转换
  • layer.transform

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

These properties triggers layout in self only

  • 无人

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

These properties does not trigger any layout

  • 中心
  • layer.anchorPoint
  • layer.position
  • alpha

我感到非常困惑,因为变换正在触发布局,而位置和anchorPoint却没有.

I find it very confusing that transform is triggering layout and that position and anchorPoint does not.

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

我想知道:

  • 为什么我会看到这种行为
  • 如果这确实前后矛盾,或者我误解了一些核心概念
  • 每次更改变换时如何避免对layoutSubviews的超级视图

我在文档或头文件中都找不到与此有关的任何内容.使用UIDynamics或类似产品时,该问题很严重.

I can not find anything about this in the docs nor the header files. The problem is significant when using UIDynamics or similar.

推荐答案

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

Apple answered me via TSI (I personally think this is rubbish):

第1部分

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

why am I seeing this behavior? is this inconsistency or am I misunderstanding some core concepts?

只要系统感觉到某些更改需要视图重新计算其子视图的框架,就会将视图标记为布局.这可能比您预期的更经常发生,并且恰好在系统选择将视图标记为需要布局的视图时,这才是实现的细节.

A view will be flagged for layout whenever the system feels something has changed that requires the view to re-calculate the frames of its subviews. This may occur more often than you'd expect and exactly when the system chooses to flag a view as requiring layout is an implementation detail.

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

why does it cascade upwards the view hierarchy?

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

Generally, changing a geometric property of a view (or layer) will trigger a cascade of layout invalidations up the view hierarchy because parent views may have Auto Layout constraints involving the modified child. Note that Auto Layout is active in some form regardless of whether you have explicitly enabled it.

如何在每次更改转换时避免对layoutSubviews的超级视图?

how can I avoid superview to layoutSubviews every time I'm changing transform?

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

There is no way to bypass this behavior. It's part of UIKit's internal bookkeeping that is required to keep the view hierarchy consistent.

第2部分

哈佛大学,

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

But if this is true I really can not understand why this does not apply to 'layer.anchorPoint' and 'center'/'layer.position'.

在这种情况下,我们可能会更加保守.父视图不需要关心孩子的位置,除非涉及自动布局".而且,如果涉及到自动"布局,则您需要直接修改约束条件,以在位置上进行持久的调整.

It may be that we are more conservative in this case. Parent views don't need to care about the position of their children except when Auto Layout gets involved. And if Auto layout were involved, you'd need to modify the constraints directly to produce a lasting adjustment in the position anyway.

此转换会触发layoutSubviews,然后再次向上层叠.

This transform triggers layoutSubviews which again cascades upwards.

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

It is my understanding that a change to the transform only invalidates the layout of the view's immediate parent (unless you have setup constraints to the changed view, then it becomes more complicated). Also, layout invalidations are batched so your parent's layout subview's method should only be called once per transaction (frame). Still, I can understand that this may cause performance issues if your layout logic is complicated.

有什么想法吗?

Any ideas?

将单元格内容包装在中间视图中.修改此中间视图的变换时,仅应禁用单元格的布局,因此不会调用您昂贵的布局方法.

Wrap your cell contents in an intermediate view. When you modify the transform of this intermediate view, only the cell's layout should be invalidated, so your expensive layout method won't be called.

如果这行不通,请创建某种机制来通知您昂贵的布局方法在其实际需要(或不需要)工作时发出信号.当您所做的唯一更改是对转换进行更改时,这可能是您设置的属性.

If that doesn't work, create some mechanism to signal to your expensive layout method when it actually does (or does not) have to do work. This could be a property you set when the only changes you make are to the transforms.

这篇关于UIView/CALayer:转换触发超级视图中的layoutSubviews的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆