IPhone Xに対応するようにアプリを更新しています。1つを除いて、すべてのビューが正常に機能します。画面全体をカバーするカスタムUIViewを表示するView Controllerがあります。 UIScreen.main.bounds
を使用してすべてのレイアウトが完了する前にビューのサイズを確認する前(collectionViewに正しいitemSizeを設定するために必要です)。 UIScreen.main.bounds.size.height - safeAreaInsets.bottom
のようなことをして、適切なサイズを使用できるようになったと思いました。問題は、safeAreaInsetsがiPhone X(シミュレーター)での試行(0,0,0,0)を返すことです。何か案は?他のビューでは、safeAreaInsetsに適切な数値を取得します。
ありがとうございました!
私はすでに解決策を考え出しています:ビューのinit
ですべての実装を行っていました。 safeAreaInsetsのサイズはlayoutSubviews()
で正しい
私は最近、viewDidLoadがトリガーされるとすぐにセーフエリアインセットが返される(0、0、0、0)という同様の問題を抱えていました。ビューの残りの部分よりも少し遅れて設定されているようです。
viewSafeAreaInsetsDidChangeをオーバーライドし、その代わりにレイアウトを実行することでそれを回避しました。
override func viewSafeAreaInsetsDidChange() {
// ... your layout code here
}
IPhone Xのキーボードに合わせてビューを上に移動しようとしても、この問題に遭遇しました。メインビューのsafeAreaInsetsは常に0です。描かれています。上記のように、私が見つけた回避策は、代わりにkeyWindowを取得し、その安全領域のインセットをチェックすることです。
Obj-C:
CGFloat bottomInset = [UIApplication sharedApplication].keyWindow.safeAreaInsets.bottom;
迅速:
let bottomInset = UIApplication.shared.keyWindow?.safeAreaInsets.bottom
その後、この値を使用して、必要に応じて制約を調整したり、フレームを表示したりできます。
別のビュー内のサブビューであるビューがあります。 safeAreaInsetsを正しく取得できないことがわかりました。layoutSubviewsに配置しても、iPhoneXのビューでは常に0を返します。最後の解決策は、次のUIScreen拡張機能を使用して、チャームのように機能する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
}
}
}
コンテナビューコントローラのviewDidAppear(_ :)メソッドは、埋め込み子ビューコントローラの安全な領域を拡張して、のビューを考慮します。
ビューがビュー階層に追加されるまで、ビューのセーフエリアインセットは正確ではないため、このメソッドで変更を行います。
override func viewDidAppear(_ animated: Bool) {
if (@available(iOS 11, *)) {
var newSafeArea = view.safeAreaInsets
// Adjust the safe area to accommodate
// the width of the side view.
if let sideViewWidth = sideView?.bounds.size.width {
newSafeArea.right += sideViewWidth
}
// Adjust the safe area to accommodate
// the height of the bottom view.
if let bottomViewHeight = bottomView?.bounds.size.height {
newSafeArea.bottom += bottomViewHeight
}
// Adjust the safe area insets of the
// embedded child view controller.
let child = self.childViewControllers[0]
child.additionalSafeAreaInsets = newSafeArea
}
}
私は同じ問題に出くわしました。私の場合、view.layoutIfNeeded()
を呼び出した後、挿入するビューのサイズは正しくなります。 view.safeAreaInsets
はこの後に設定されましたが、top
の値のみが正しいものでした。一番下の値はまだ0
(iPhone Xの場合)です。
safeAreaInsets
が正しく設定されているポイントを把握しようとしている間に、ビューのsafeAreaInsetsDidChange()
メソッドにブレークポイントを追加しました。これは複数回呼び出されていましたが、バックトレースでCALayer.layoutSublayers()
が表示されたときにのみ値が正しく設定されていました。
view.layoutIfNeeded()
をCALayer
の対応するview.layer.layoutIfNeeded()
に置き換えた結果、safeAreaInsets
がすぐに正しく設定され、問題が解決しました。
TL; DR
交換
view.layoutIfNeeded()
沿って
view.layer.layoutIfNeeded()
[UIApplication sharedApplication].keyWindow.safeAreaInsets return none zero
self.view.safeAreaInsets
の代わりにUIApplication.shared.keyWindow?.safeAreaInsets
を試してください。アプリケーションのkeyWindowを介して要求された場合、iOS 11.x.xデバイスではセーフエリアのインセットが塗りつぶされないようです。