子视图图层转换和layoutSubviews

Luc*_*tti 3 core-animation objective-c uiview ios autolayout

我的问题与

UIView/CALayer:转换在superview中触发layoutSubviews

据报道,来自苹果的TSI回复:

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

在我的情况下,我有一个非常简单的视图层次结构,其中视图A包含视图B.

A的布局子视图中设置B的帧.

当我在B的背衬层上执行动画(变换和不透明)时,有时会调用A的layoutSubviews.这显然是一个问题,因为我在A的layoutSubviews中设置了B的框架,这打破了动画.

如何避免B的布局和动画之间的这种冲突?

Luc*_*tti 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;
Run Code Online (Sandbox Code Playgroud)

2)在不触摸框架的情况下更改视图的边界和中心.边界和中心似乎不会影响变换.有意义,因为帧是在内部计算读取图层的边界,位置,变换,锚点.

self.internalView.bounds = self.bounds;
self.internalView.center = CGPointMake(floorf(CGRectGetWidth(self.bounds)/2.0f),        floorf(CGRectGetHeight(self.bounds)/2.0f));
Run Code Online (Sandbox Code Playgroud)

3) TSI中的Apple(此处报告UIView/CALayer:转换触发layoutview中的superSview视图)建议

"在中间视图中包装单元格内容.修改此中间视图的变换时,只应该使单元格的布局无效,因此不会调用昂贵的布局方法.

如果这不起作用,请创建一些机制,以便在实际(或不)必须执行工作时向您的昂贵布局方法发出信号.当您对变换进行的唯一更改时,这可能是您设置的属性."

4)我还尝试关闭自定义视图的子视图的完全自动布局.你可以从obj.io中读到这篇非常好的文章,其中解释说如果你从layoutSubviews实现中删除对[super layoutSubviews]的调用,你会选择自动布局来自定义视图及其所有子视图.

踩踏是你必须意识到,如果你添加一个带有约束的视图作为子视图,autolayout系统将会出现如下异常:

***由于未捕获的异常'NSInternalInconsistencyException'而终止应用程序,原因:'执行-layoutSubviews后仍需要自动布局.MyView的-layoutSubviews实现需要调用super.

如果你有一个简单的布局逻辑,解决方案1和2是很好的.如果您的布局逻辑是扩展的,您可以实现3或4并裁判到另一个问题UIView/CALayer:Transform触发layoutviewubviews in superview