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?
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.
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
}
}
}