webentwicklung-frage-antwort-db.com.de

safeAreaInsets geben falsche Werte in viewDidLoad zurück. Wo ist der beste Ort, um sie zu erhalten?

Wenn ich versuche, die safeAreaInsets in viewDidLoad in meinem View-Controller abzurufen, wird auf dem iPhone X (0, 0, 0, 0) zurückgegeben, was falsch ist. Die Dokumentation besagt, dass dies der Fall ist, wenn die Ansicht nicht Teil der Hierarchie ist oder die Ansicht nicht sichtbar ist. Meine Frage lautet also: Wo ist der beste Ort, um die safeAreaInsets abzurufen und dann meine Unteransichten mit diesen Insets zu gestalten? 

11
Saoud Rizwan

Sie müssen viewDidLayoutSubviews anstelle von viewDidLoad verwenden.

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
    // your layout code here
}

Hinweis: Im Gegensatz zu viewDidLoad, das nur einmal aufgerufen wird, wird viewDidLayoutSubviews häufig mehrmals aufgerufen. Stellen Sie sicher, dass Sie nur die Frames in viewDidLayoutSubviews setzen, und führen Sie keine Operationen aus, die nur einmal ausgeführt werden sollten, wie z.

14
nathangitter

Ich habe eine benutzerdefinierte Ansicht, die eine Inhaltsansicht einer Bildlaufansicht ist und Zeichnen der UI mit drawrect. .__ Die Inhaltsansicht wird entsprechend ihrer Größe gezeichnet, sodass ich die Breite des sicheren Bereichs in meiner Drawrect-Funktion erhalten muss. Es stellt sich heraus, dass ich safeAreaInsets nicht korrekt abrufen kann, es wird immer Null zurückgegeben, obwohl ich es in Layoutsubviews setze. Ich fand schließlich die Antwort, dass ich safeAreaInsets erfolgreich durch UIApplication.shared.keyWindow erhalten kann.

Hier ist meine Lösung

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

        }

    }

}
0
Shih Ken