当子视图不在视图区域中时,安全区域在 iPhone X 上无法正常工作
Posted
技术标签:
【中文标题】当子视图不在视图区域中时,安全区域在 iPhone X 上无法正常工作【英文标题】:Safe area not work properly on iPhone X when subviews are not in the view area 【发布时间】:2017-09-18 03:28:14 【问题描述】:我有一个包含 2 个子 viewController 的 scrollView。您可以看到 VC2 的布局不正确。
我发现屏幕上是否还看不到视图。
safeAreaInsets
始终为 0。
滚动结束时,我可以致电vc2.view.setNeedsLayout()
解决此问题。
但是在滚动结束之前布局是不正确的。
document 说
如果视图当前未安装在视图层次结构中,或者未安装 但在屏幕上可见,此属性中的边缘插图为 0。
那么我该如何解决这种情况。
自动布局
【问题讨论】:
您需要提供更多信息,向我们展示“VC1 Bottom”和“VC2 Bottom”的约束是什么样的。它们完全一样吗? 是的。它们是相同的约束中心到安全区域和底部到安全区域。 您是否厌倦了将vc2.view.setNeedsLayout()
放入viewDidLayoutSubviews()
或类似的东西? (通过适当的测试来防止潜在的无限循环)
viewDidLayoutSubviews()
是一样的。当视图不在屏幕上时,安全区域始终为 0。
找到任何解决方案?我有同样的问题,针对 ios10 我不能使用safeAreaInsets
【参考方案1】:
不引用当前视图的 safeAreaInsets,而是将其设置为 UIApplication:
(UIApplication.shared.delegate?.window??.safeAreaInsets.bottom)
【讨论】:
safeAreaInsets
仅适用于 iOS 11.0 或更高版本
没关系,afaiak 旧设备无论如何都没有 safeAreaInsets【参考方案2】:
在您的子视图控制器中,如果您将视图控制器 additionalSafeAreaInsets
设置为窗口的安全区域插图,它们将根据安全区域正确布局。
我发现我必须在 viewDidLoad()
和 viewWillTransition(to size: CGSize, with coordinator: UIVIewControllerTransitionCoordinator
内部执行此操作
在viewWillTransition
内部,您需要在协调器的动画块中设置additionalSafeAreaInsets
:
coordinator.animate(alongsideTransition: _ in
if #available(iOS 11.0, *)
self.additionalSafeAreaInsets = UIApplication.shared.delegate?.window??.safeAreaInsets
, completion: nil)
【讨论】:
【参考方案3】:我正在构建一个自定义分页视图控制器,并且@PowHU 也遇到了这个问题。
似乎对我有用的唯一解决方案是将情节提要中的视图控制器的视图类设置为我创建的名为 AlwaysSafeAreaInsetsView
的自定义类。
import UIKit
class AlwaysSafeAreaInsetsView: UIView
@available(iOS 11.0, *)
override var safeAreaInsets: UIEdgeInsets
if let window = UIApplication.shared.keyWindow
return window.safeAreaInsets
return super.safeAreaInsets
【讨论】:
【参考方案4】:如果我没看错,您的容器视图将固定在其父视图的顶部和底部。将其固定到安全区域,您的子视图控制器将正确布局。
【讨论】:
没有。我希望容器视图与 superView 大小相同。以上是关于当子视图不在视图区域中时,安全区域在 iPhone X 上无法正常工作的主要内容,如果未能解决你的问题,请参考以下文章
iPhone X 将对象底部对齐到安全区域废墟在其他设备上的外观