我有一个scrollView包含2个子viewController。您会发现VC2的布局不正确。
我发现,如果视图尚未在屏幕上可见,则safeAreaInsets
始终为0。
当滚动结束时,我可以调用vc2.view.setNeedsLayout()
来解决此问题。但是直到滚动结束后布局才被修正。
文档说:
如果视图当前未安装在视图层次结构中或尚未显示在屏幕上,则此属性中的边缘插图为0。
那么我该如何解决这种情况呢?
我有一个scrollView包含2个子viewController。您会发现VC2的布局不正确。
我发现,如果视图尚未在屏幕上可见,则safeAreaInsets
始终为0。
当滚动结束时,我可以调用vc2.view.setNeedsLayout()
来解决此问题。但是直到滚动结束后布局才被修正。
文档说:
如果视图当前未安装在视图层次结构中或尚未显示在屏幕上,则此属性中的边缘插图为0。
那么我该如何解决这种情况呢?
不要引用当前视图的safeAreaInsets,而是将其设置为UIApplication:
(UIApplication.shared.delegate?.window??.safeAreaInsets.bottom)
safeAreaInsets
仅在目标 iOS 11.0 或更高版本上可用。 - Giovanni Trezzi 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)
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
}
}
viewDidLayoutSubviews()
或类似的地方放置vc2.view.setNeedsLayout()
?(附带适当的测试以防止潜在的无限循环) - ZaphodviewDidLayoutSubviews()
是相同的。当视图不在屏幕上时,安全区域始终为0。 - PowHusafeAreaInsets
。 - Giovanni TrezziUIScrollView
,这意味着需要使用一些技巧来布置滚动视图中的子视图。本文档提供了一些技术概述:https://developer.apple.com/library/content/documentation/UserExperience/Conceptual/AutolayoutPG/WorkingwithScrollViews.html - Yevhen Dubinin