当我尝试在视图控制器中检索viewDidLoad中的safeAreaInsets时,它会在iPhone X上返回(0,0,0,0),我知道这是错误的。文档说如果视图不是层次结构的一部分或视图不可见,则会发生这种情况。所以我的问题是,检索safeAreaInsets然后使用这些插图布局我的子视图的最佳位置在哪里?
当我尝试在视图控制器中检索viewDidLoad中的safeAreaInsets时,它会在iPhone X上返回(0,0,0,0),我知道这是错误的。文档说如果视图不是层次结构的一部分或视图不可见,则会发生这种情况。所以我的问题是,检索safeAreaInsets然后使用这些插图布局我的子视图的最佳位置在哪里?
你需要使用 viewDidLayoutSubviews
代替 viewDidLoad
。
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
// your layout code here
}
注意: 不像 viewDidLoad
只召唤一次, viewDidLayoutSubviews
通常被称为多次。确保仅在内部设置框架 viewDidLayoutSubviews
,并且不执行仅应该发生一次的操作,例如添加子视图。
我有一个自定义视图,它是滚动视图的内容视图,使用drawrect绘制UI。 内容视图是根据其大小绘制的,因此我需要在drawrect函数中获得安全区域宽度。 事实证明,我无法正确获得safeAreaInsets,即使我把它放在layoutsubviews中也总是返回零。 我终于找到答案是我可以通过UIApplication.shared.keyWindow成功获得safeAreaInsets。
这是我的解决方案
extension UIScreen {
func widthOfSafeArea() -> CGFloat {
guard let rootView = UIApplication.shared.keyWindow else { return 0 }
if #available(iOS 11.0, *) {
let leftInset = rootView.safeAreaInsets.left
let rightInset = rootView.safeAreaInsets.right
return rootView.bounds.width - leftInset - rightInset
} else {
return rootView.bounds.width
}
}
func heightOfSafeArea() -> CGFloat {
guard let rootView = UIApplication.shared.keyWindow else { return 0 }
if #available(iOS 11.0, *) {
let topInset = rootView.safeAreaInsets.top
let bottomInset = rootView.safeAreaInsets.bottom
return rootView.bounds.height - topInset - bottomInset
} else {
return rootView.bounds.height
}
}
}