web-dev-qa-db-fra.com

safeAreaInsets renvoie des valeurs incorrectes dans viewDidLoad, quel est le meilleur endroit pour l'obtenir?

Lorsque j'essaie de récupérer les safeAreaInsets dans viewDidLoad dans mon contrôleur de vue, il renvoie (0, 0, 0, 0) sur l'iPhone X, ce qui, à mon avis, est erroné. La documentation indique que cela se produira si la vue ne fait pas partie de la hiérarchie ou si la vue n'est pas visible. Ma question est donc la suivante: quel est le meilleur endroit pour extraire les safeAreaInsets, puis pour agencer mes sous-vues à l'aide de ces incrustations? 

11
Saoud Rizwan

Vous devez utiliser viewDidLayoutSubviews au lieu de viewDidLoad.

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

Remarque: Contrairement à viewDidLoad qui n'est appelé qu'une seule fois, viewDidLayoutSubviews est souvent appelé plusieurs fois. Assurez-vous de ne définir que les cadres dans viewDidLayoutSubviews et n'effectuez pas d'opérations qui ne devraient se produire qu'une seule fois, comme l'ajout de sous-vues.

14
nathangitter

J'ai une vue personnalisée, qui est une vue de contenu d'une vue de défilement, en utilisant drawrect pour dessiner l'interface utilisateur. La vue du contenu est dessinée en fonction de sa taille, je dois donc obtenir une largeur de zone sécurisée dans ma fonction drawrect. Il s'avère que je ne parviens pas à obtenir safeAreaInsets correctement, il renvoie toujours zéro même si je le mets dans layoutsubviews. J'ai finalement trouvé que la réponse était que je pouvais obtenir safeAreaInsets avec UIApplication.shared.keyWindow.

Voici ma solution

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