UIView/CALayer: Transform 在 superview 中触发 layoutSubviews [英] UIView/CALayer: Transform triggers layoutSubviews in superview

查看:22
本文介绍了UIView/CALayer: Transform 在 superview 中触发 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.

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

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
  • 层.位置
  • 阿尔法

我发现转换会触发布局而位置和锚点不会触发这一点非常令人困惑.

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

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

我想知道:

  • 为什么我会看到这种行为
  • 如果这真的是不一致的,或者我误解了一些核心概念
  • 如何在每次更改转换时避免 superview 到 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.

如何在每次更改转换时避免 superview 到 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.

有什么想法吗?

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

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: Transform 在 superview 中触发 layoutSubviews的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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