ios - subview 层变换和布局 subview

标签 ios objective-c uiview core-animation autolayout

我的问题是关于

UIView/CALayer: Transform triggers layoutSubviews in superview

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

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.

在我的例子中,我有一个非常简单的 View 层次结构,其中 View A 包含 View B

A 的布局 subview 中,我正在设置 B 的框架。

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

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

最佳答案

我发现可以通过多种方式解决这个问题:

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) 在不触摸框架的情况下更改 View 的边界和中心。边界和中心似乎不影响转换。这是有道理的,因为帧是在内部计算读取层的边界、位置、变换、 anchor 。

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)建议

"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."

4) 我还尝试完全关闭自定义 View subview 的自动布局。您可以从 obj.io 阅读这篇非常好的文章其中解释说,如果您从 layoutSubviews 实现中删除对 [super layoutSubviews] 的调用,您将选择退出自定义 View 及其所有 subview 的自动布局。

问题在于,您必须意识到,如果您将带有约束的 View 添加为 subview ,自动布局系统将引发如下异常:

*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Auto Layout still required after executing -layoutSubviews. MyView's implementation of -layoutSubviews needs to call super.'

如果您的布局逻辑简单,则解决方案 1 和 2 很好。如果您的布局逻辑很广泛,您可以实现 3 或 4 并引用另一个问题 UIView/CALayer: Transform triggers layoutSubviews in superview

关于ios - subview 层变换和布局 subview ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25143912/

相关文章:

ios - 在 View Controller 之间传递数据

php - 在 iOS 上从网页请求 BLOB

objective-c - 使用 NSScanner 从最后一个字符实例扫描到字符串结尾

objective-c - iOS7 Sprite Kit如何将交互式Sprite Nodes和交互式UIViews结合起来?

ios - 在哪里以编程方式构建 View 与使用 Nib

objective-c - 更改 UIViewController self.view 框架

objective-c - iOS 上是否有类似 MVVM 的 objective-c 框架?

ios - 检测一个 UIView 何时位于另一个 UIView 之上

ios - 将 `RxTableViewSectionedAnimatedDataSource` 绑定(bind)到 UITableView 时生成错误

ios - UITableView tableHeaderView 中的 UIButton 不响应触摸