viewDidLoad est la première méthode qu’UIKit appelle après avoir chargé la View de UIViewController en mémoire. Selon Apple Developer Documentation, cette méthode est appelée exactement une fois pendant toute la durée de vie du contrôleur. viewDidLoad est l’endroit principal pour la configuration initiale de l’interface, l’enregistrement des cellules et l’initialisation des données.
Points clés
viewDidLoad est une méthode d’instance de UIViewController qu’UIKit appelle immédiatement après que la View du contrôleur a été chargée en mémoire. À ce stade, toutes les propriétés IBOutlet sont déjà connectées aux éléments de l’interface, mais la View n’a pas encore été ajoutée à la hiérarchie des fenêtres et n’est pas visible pour l’utilisateur. Le développeur redéfinit cette méthode pour effectuer la configuration initiale de l’écran.
Cette méthode fait partie du ViewController Lifecycle et vient immédiatement après loadView si la View est créée par programmation, ou après le chargement depuis le Storyboard. Dans un projet typique, viewDidLoad est la méthode la plus souvent redéfinie de UIViewController, car elle fournit un point sécurisé pour travailler avec les subviews qui existent déjà et sont prêtes à être configurées.
Un détail important : au moment où viewDidLoad est appelé, les dimensions de la View ne correspondent pas encore aux dimensions finales — Auto Layout n’a pas terminé ses passages, et le frame peut différer des attentes. Pour les calculs qui dépendent des dimensions, utilisez viewDidLayoutSubviews.
Le moment de l’appel de viewDidLoad dépend de la façon dont le contrôleur est initialisé. Dans la plupart des cas, UIKit appelle cette méthode automatiquement lors du premier accès à la propriété view du contrôleur — c’est ce qu’on appelle le mécanisme de lazy-loading de UIViewController.
Lorsqu’un NavigationController ou TabBarController affiche votre écran pour la première fois, UIKit vérifie si la View est chargée. Si ce n’est pas le cas — loadView est appelé (ou chargement depuis le Storyboard), après quoi viewDidLoad est déclenché immédiatement. C’est le scénario standard, et il se produit une fois pour chaque instance de contrôleur.
override func viewDidLoad() {
super.viewDidLoad()
print("View chargée — vous pouvez configurer l’interface")
setupUI()
configureTableView()
}
viewDidLoad n’est pas rappelé lors du retour à l’écran via le bouton retour ou dismiss. Si votre logique dépend de la réapparition de l’écran — placez-la dans viewWillAppear. C’est l’une des erreurs conceptuelles les plus fréquentes : les développeurs s’attendent à ce que viewDidLoad se déclenche à chaque affichage, mais UIKit ne l’appelle qu’une seule fois.
Parfois, les développeurs accèdent de force à la view du contrôleur pour déclencher le chargement à l’avance : let _ = controller.view. Cela force l’appel de loadView et viewDidLoad avant que le contrôleur n’apparaisse à l’écran. Cette technique est utilisée lorsque vous devez préparer la View à l’avance pour une transition fluide.
viewDidLoad est destiné aux opérations de configuration ponctuelles qui ne dépendent pas du fait que l’écran soit visible. L’utilisation correcte de cette méthode est la clé d’une architecture propre et d’un comportement prévisible du contrôleur.
Dans viewDidLoad, on enregistre les fichiers nib et les classes pour UITableView et UICollectionView, on configure les delegates et on définit les valeurs initiales des propriétés des éléments UI. Comme tous les IBOutlet sont déjà connectés à ce stade, on peut accéder en toute sécurité à label.text, imageView.image et aux autres propriétés des subviews.
override func viewDidLoad() {
super.viewDidLoad()
tableView.dataSource = self
tableView.delegate = self
tableView.register(
CustomCell.self,
forCellReuseIdentifier: CustomCell.identifier
)
title = "Écran principal"
}
Ici, on crée une viewModel, on initialise la data source avec des tableaux et on s’abonne aux notifications qui doivent être actives pendant toute la durée de vie du contrôleur. Par exemple, s’abonner à UIApplication.willEnterForegroundNotification pour mettre à jour les données lors du retour de l’arrière-plan est un bon candidat pour viewDidLoad. La viewModel dans l’architecture iOS moderne agit comme un pont entre le contrôleur et la logique métier, et l’initialiser dans viewDidLoad garantit que les données sont prêtes au moment de la première apparition de l’écran.
Portez une attention particulière à la configuration de la data source pour les tables et les collections. Si votre table utilise UIFetchedResultsController ou NSFetchedResultsController avec Core Data, initialisez la fetch request et le delegate dans viewDidLoad. Cela garantit que lors de la première apparition de l’écran, la table sera déjà remplie de données sans requêtes supplémentaires.
Dans viewDidLoad, on configure les boutons de la NavigationBar, on définit le large title, on ajoute le search controller et on définit les boutons edit/done. Ces éléments changent rarement lors des réaffichages de l’écran, donc les initialiser ici est optimal.
Toutes les opérations ne sont pas appropriées dans viewDidLoad. Certaines actions placées dans cette méthode entraînent une consommation excessive de mémoire, un comportement incorrect ou des bogues lors du réaffichage de l’écran.
Évitez de lancer des requêtes réseau dont le résultat n’affecte que l’UI. Si la requête se termine avant l’apparition de l’écran, l’utilisateur ne verra pas le résultat, et si elle se termine après — les données peuvent être obsolètes. Lancez le chargement dans viewDidLoad, mais mettez à jour l’UI dans viewWillAppear.
N’effectuez pas dans viewDidLoad des opérations qui dépendent de la taille et de la position de la View. Au moment de l’appel, Auto Layout n’a pas terminé ses passages et le frame peut ne pas être définitif. Pour les calculs, utilisez viewDidLayoutSubviews ou redéfinissez updateViewConstraints.
Ne vous abonnez pas aux notifications qui ne sont pertinentes que lorsque l’écran est visible. Notifications de clavier, notifications de changement de contenu des contrôleurs enfants — abonnez-vous dans viewWillAppear et désabonnez-vous dans viewDidDisappear pour éviter les appels inutiles et les fuites.
N’appelez pas de méthodes qui nécessitent un écran visible. Par exemple, essayer d’afficher un UIAlertController depuis viewDidLoad générera une erreur car la View du contrôleur n’a pas encore été ajoutée à la hiérarchie des fenêtres. Toute opération UI qui dépend de la fenêtre ou de presentedViewController doit être exécutée seulement après l’apparition de l’écran.
N’initialisez pas de ressources lourdes inutilement. Si l’écran est rarement affiché ou si les données ne sont pas affichées immédiatement, reportez la création d’objets gourmands en ressources jusqu’à ce qu’ils soient vraiment nécessaires. L’initialisation paresseuse (lazy) des propriétés en Swift est un mécanisme intégré pour résoudre ce problème : une propriété avec le modificateur lazy ne sera créée qu’au premier accès, économisant de la mémoire et accélérant le chargement de l’écran.
N’utilisez pas viewDidLoad pour les opérations qui doivent être exécutées chaque fois que l’écran apparaît. C’est l’erreur la plus fondamentale : les développeurs débutants placent souvent la logique de mise à jour des données dans viewDidLoad et sont surpris que lors du retour d’un autre écran, la table ne se recharge pas. Si une opération doit se répéter à chaque affichage — utilisez viewWillAppear. Si elle doit s’exécuter une fois par durée de vie — utilisez viewDidLoad. Souvenez-vous de cette règle simple pour éviter la plupart des problèmes avec le cycle de vie de UIViewController.
Regardons trois exemples pratiques montrant l’utilisation correcte de viewDidLoad dans des projets réels. Chaque exemple résout une tâche spécifique de configuration d’écran.
override func viewDidLoad() {
super.viewDidLoad()
collectionView.register(
PhotoCell.self,
forCellWithReuseIdentifier: PhotoCell.reuseId
)
collectionView.register(
HeaderView.self,
forSupplementaryViewOfKind: UICollectionView.elementKindSectionHeader,
withReuseIdentifier: HeaderView.reuseId
)
viewModel.delegate = self
viewModel.fetchInitialPage()
}
override func viewDidLoad() {
super.viewDidLoad()
let label = UILabel()
label.text = "Bonjour le monde !"
label.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(label)
NSLayoutConstraint.activate([
label.centerXAnchor.constraint(equalTo: view.centerXAnchor),
label.centerYAnchor.constraint(equalTo: view.centerYAnchor)
])
}
Dans viewDidLoad, on configure également les éléments affichés en l’absence de données : état vide, loader, placeholder. Ces composants sont créés une fois et réutilisés chaque fois que l’écran apparaît. Le masquage ou l’affichage de ces éléments est géré dans viewWillAppear en fonction des données actuelles.
override func viewDidLoad() {
super.viewDidLoad()
emptyStateLabel = UILabel()
emptyStateLabel.text = "Aucune donnée"
emptyStateLabel.textAlignment = .center
emptyStateLabel.isHidden = true
view.addSubview(emptyStateLabel)
activityIndicator = UIActivityIndicatorView(style: .medium)
activityIndicator.hidesWhenStopped = true
view.addSubview(activityIndicator)
}
override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver(
self,
selector: #selector(handleEnterForeground),
name: UIApplication.willEnterForegroundNotification,
object: nil
)
}
@objc private func handleEnterForeground() {
refreshContent()
}
Foire aux questions
Dans des conditions normales, non — UIKit appelle viewDidLoad une fois après avoir chargé la View en mémoire. Si le contrôleur est détruit et recréé, viewDidLoad s’exécutera pour la nouvelle instance.
Oui, absolument. L’appel à super.viewDidLoad garantit qu’UIKit effectue la configuration interne nécessaire au bon fonctionnement du Lifecycle. Appelez toujours super en premier dans la méthode.
viewDidLoad est appelé une fois lors du chargement de la View. viewWillAppear est appelé chaque fois avant l’apparition de l’écran. Le premier est pour la configuration unique, le second pour la mise à jour des données et de l’état.
Les opérations synchrones lourdes dans viewDidLoad bloquent le thread principal et retardent l’apparition de l’écran. Les chargements asynchrones sont acceptables, mais lors de la mise à jour de l’UI à la fin, il faut tenir compte du fait que l’écran peut déjà être masqué.
Vous ne pouvez pas appeler viewDidLoad directement — UIKit l’appelle. Pour forcer le chargement de la View, accédez à la propriété controller.view. Cela déclenchera automatiquement loadView et viewDidLoad.
Résumé
Nous développerons une application mobile clé en main
IT Sectr crée des applications iOS et Android pour les startups et les entreprises depuis 2017. Nous vous conseillerons et vous proposerons la meilleure solution.
Lisez aussi