我的问题与
有关UIView/CALayer: Transform triggers layoutSubviews in superview
据报道,来自苹果的TSI回复:
通常,更改视图(或图层)的几何属性 在视图层次结构中触发级联布局失效 因为父视图可能有涉及的自动布局约束 修改后的孩子请注意,自动布局以某种形式激活 无论您是否已明确启用它。
在我的情况下,我有一个非常简单的视图层次结构,其中视图 A 包含视图 B
在 A 的layoutSubviews中,我设置了 B 的框架。
当我在B的背衬层上执行动画(变换和不透明度)时,有时会调用A的layoutSubviews。这显然是一个问题,因为我在A的layoutSubviews中设置了B的框架,这打破了动画。
如何避免B的布局与动画之间的这种冲突?
答案 0 :(得分:13)
我发现可以通过多种方式解决这个问题:
1)临时保存转换,更改框架,然后重新应用转换:
[super layoutSubviews];
//backup the transform value before the layout
CATransform3D transform = self.internalView.layer.transform;
//Set identity and update all the necessary frames
self.internalView.layer.transform = CATransform3DIdentity;
self.internalView.frame = self.bounds;
//set back the transform
self.internalView.layer.transform = transform;
2)更改视图的边界和中心而不触摸框架。边界和中心似乎不会影响变换。有意义,因为帧是在内部计算读取图层的边界,位置,变换,锚点。
self.internalView.bounds = self.bounds;
self.internalView.center = CGPointMake(floorf(CGRectGetWidth(self.bounds)/2.0f), floorf(CGRectGetHeight(self.bounds)/2.0f));
3) TSI中的Apple(此处报告为UIView/CALayer: Transform triggers layoutSubviews in superview)建议
“将您的单元格内容包装在中间视图中。修改时 转换这个中间视图,只应该是单元格的布局 无效,因此不会调用昂贵的布局方法。
如果这不起作用,请创建一些机制来向您发出信号 实际上(或不)必须做的昂贵的布局方法 工作。这可能是您在进行唯一更改时设置的属性 是转型。“
4)我还尝试关闭自定义视图的子视图的完全自动布局。您可以从obj.io阅读这篇非常好的文章,其中解释说,如果您从 layoutSubviews 实施中移除对 [super layoutSubviews] 的调用,那么您选择了自动布局用于自定义视图及其所有子视图。
你需要注意的是,你必须要知道,如果你在子视图中添加一个带有约束的视图,autolayout系统将会出现如下异常:
***因未捕获的异常'NSInternalInconsistencyException'而终止应用程序,原因:'自动布局仍然 执行-layoutSubviews后需要。 MyView的实现 -layoutSubviews需要调用super。'
如果你有一个简单的布局逻辑,解决方案1和2是很好的。如果您的布局逻辑是扩展的,您可以实现3或4并裁判另一个问题UIView/CALayer: Transform triggers layoutSubviews in superview