我发现可以通过多种方式解决这个问题:
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)Apple 进入 TSI(此处报道UIView/CALayer:变换触发超级视图中的layoutSubviews https://stackoverflow.com/questions/24632876/uiview-calayer-transform-triggers-layoutsubviews-in-superview)建议
“将单元格内容包装在中间视图中。当您修改
变换这个中间视图,只有单元格的布局应该是
无效,因此不会调用昂贵的布局方法。
如果这不起作用,请创建一些机制来向您发出信号
昂贵的布局方法,当它实际上需要(或不需要)时
工作。这可能是您在进行唯一更改时设置的属性
是为了变换。”
4)我还尝试关闭自定义视图的子视图的完全自动布局。您可以阅读这篇非常好的文章obj.io http://www.objc.io/issue-3/advanced-auto-layout-toolbox.html其中解释了如果您删除对[超级布局子视图]来自布局子视图实现您正在为自定义视图及其所有子视图选择退出自动布局。
要点是,您必须意识到,如果您将带有约束的视图添加为子视图,自动布局系统将出现如下异常:
*** 由于未捕获的异常“NSInternalInconsistencyException”而终止应用程序,原因:“自动布局仍然存在”
执行-layoutSubviews后需要。 MyView 的实现
-layoutSubviews 需要调用 super。'
如果您有简单的布局逻辑,解决方案 1 和 2 就很好。如果您的布局逻辑很广泛,您可以实现 3 或 4 并参考另一个问题UIView/CALayer:变换触发超级视图中的layoutSubviews https://stackoverflow.com/questions/24632876/uiview-calayer-transform-triggers-layoutsubviews-in-superview/24673063?noredirect=1#comment39243731_24673063