ビューコントローラーのviewDidLoadでsafeAreaInsetsを取得しようとすると、iPhone Xで(0、0、0、0)が返されますが、これは間違いです。ドキュメントには、ビューが階層の一部でない場合、またはビューが表示されない場合に発生することが記載されています。だから私の質問は、safeAreaInsetsを取得し、これらのインセットを使用してサブビューをレイアウトするのに最適な場所はどこですか?
viewDidLayoutSubviews
の代わりにviewDidLoad
を使用する必要があります。
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
// your layout code here
}
注:一度しか呼び出されないviewDidLoad
とは異なり、viewDidLayoutSubviews
は複数回呼び出されることがよくあります。 viewDidLayoutSubviews
内のフレームのみを設定してください。サブビューの追加など、1回だけ発生するはずの操作を実行しないでください。
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
}
}
}