ios - 取得 - viewsafeareainsetsdidchange




iPhoneViewでUIViewのsafeAreaInsetsが0になっています (4)

私はiPhone Xのためにそれを適応させるために私のアプリを更新しています。 私は、画面全体をカバーするカスタムUIViewを表示するビューコントローラを持っています。 UIScreen.main.boundsを使用してすべてのレイアウトが完了する前に、ビューのサイズを調べる前に(collectionViewに正しいitemSizeを配置するために必要でした) 私は今、正しい使用可能なサイズを得るために、 UIScreen.main.bounds.size.height - safeAreaInsets.bottomようなことをすることができると考えました。 問題は、safeAreaInsetsが(0,0,0,0)iPhone X(Simulator)で試行していることです。 何か案は? 他のビューでは、私はsafeAreaInsetsの正しい番号を取得します。

ありがとうございました!


コンテナビューコントローラの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
  } 
}

私はiPhoneのキーボードのための道を作るためにビューを移動しようとしているこの問題にも走ってきた。メインビューのsafeAreaInsetsは、サブビューがこの時点でスクリーンとしてレイアウトされていることは分かっているが描かれている。 上記のように私が見つけた解決策は、keyWindowを取得し、安全領域のインセットを確認することです。

Obj-C:

CGFloat bottomInset = [UIApplication sharedApplication].keyWindow.safeAreaInsets.bottom;

迅速:

let bottomInset = UIApplication.shared.keyWindow?.safeAreaInsets.bottom

この値を使用して、必要に応じて制約を調整したり、フレームを表示したりすることができます。


私は別のビューの中のサブビューであるビューを持っています。 私はsafeAreaInsetsを正しく取得できないことがわかりました。たとえlayoutSubviewsに入れてもiPhoneXのビューで常に0を返します。 最終的な解決策は、safeAreaInsetsを検出するためにUIScreen拡張を使用して、魅力的に動作することです。

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

        }

    }

}

私は同じ問題に遭遇しました。 私の場合は、 view.layoutIfNeeded()呼び出した後、挿入しているビューのサイズが正しく設定されます。 この後にview.safeAreaInsetsが設定されましたが、 top値だけが正しいです。 下の値はまだ0 (これはiPhone Xの場合)でした。

どの時点でsafeAreaInsetsが正しく設定されているかをsafeAreaInsetsに、ビューのsafeAreaInsetsDidChange()メソッドにブレークポイントを追加しました。 これは複数回呼び出されていましたが、バックトレースでCALayer.layoutSublayers()が正しく認識されていたときにのみ表示されます。

ですから、 view.layoutIfNeeded()CALayerの対応するview.layer.layoutIfNeeded()に置き換えました。これにより、 safeAreaInsetsが正しく設定され、問題が解決されました。

TL; DR

置換

view.layoutIfNeeded()

によって

view.layer.layoutIfNeeded()




iphone-x