viewDidLoad es el primer método que UIKit llama después de cargar la View de UIViewController en memoria. Según Apple Developer Documentation, este método se llama exactamente una vez durante toda la vida del controlador. viewDidLoad es el lugar principal para la configuración inicial de la interfaz, el registro de celdas y la inicialización de datos.
Puntos clave
viewDidLoad es un método de instancia de UIViewController que UIKit llama inmediatamente después de que la View del controlador se ha cargado en memoria. En este punto, todas las propiedades IBOutlet ya están conectadas a los elementos de la interfaz, pero la View aún no se ha añadido a la jerarquía de ventanas y no es visible para el usuario. El desarrollador sobrescribe este método para realizar la configuración inicial de la pantalla.
El método forma parte del ViewController Lifecycle y sigue inmediatamente después de loadView si la View se crea mediante programación, o después de la carga desde Storyboard. En un proyecto típico, viewDidLoad es el método más sobrescrito de UIViewController, ya que proporciona un punto seguro para trabajar con subviews que ya existen y están listas para configurarse.
Un detalle importante: cuando se llama a viewDidLoad, las dimensiones de la View aún no corresponden a las finales — Auto Layout no ha completado sus pasos, y el frame puede diferir de lo esperado. Para cálculos que dependen de dimensiones, usa viewDidLayoutSubviews.
El momento de la llamada a viewDidLoad depende de cómo se inicialice el controlador. En la mayoría de los casos, UIKit llama a este método automáticamente la primera vez que se accede a la propiedad view del controlador — esto se llama el mecanismo lazy-loading de UIViewController.
Cuando un NavigationController o TabBarController muestra tu pantalla por primera vez, UIKit comprueba si la View está cargada. Si no — se llama a loadView (o carga desde Storyboard), tras lo cual se activa inmediatamente viewDidLoad. Este es el escenario estándar y ocurre una vez por cada instancia del controlador.
override func viewDidLoad() {
super.viewDidLoad()
print("View cargada — puedes configurar la interfaz")
setupUI()
configureTableView()
}
viewDidLoad no se vuelve a llamar al regresar a la pantalla mediante el botón de retroceso o dismiss. Si tu lógica depende de que la pantalla aparezca de nuevo — colócala en viewWillAppear. Este es uno de los errores conceptuales más comunes: los desarrolladores esperan que viewDidLoad se ejecute en cada visualización, pero UIKit lo llama solo una vez.
A veces los desarrolladores acceden forzosamente a la view del controlador para activar la carga anticipadamente: let _ = controller.view. Esto fuerza la llamada a loadView y viewDidLoad antes de que el controlador aparezca en pantalla. Esta técnica se usa cuando se necesita preparar la View con antelación para una transición suave.
viewDidLoad está diseñado para operaciones de configuración únicas que no dependen de si la pantalla es visible. El uso correcto de este método es la clave para una arquitectura limpia y un comportamiento predecible del controlador.
En viewDidLoad se registran archivos nib y clases para UITableView y UICollectionView, se configuran delegados y se establecen valores iniciales de las propiedades de los elementos UI. Como todos los IBOutlet ya están conectados en este punto, se puede acceder de forma segura a label.text, imageView.image y otras propiedades de las subviews.
override func viewDidLoad() {
super.viewDidLoad()
tableView.dataSource = self
tableView.delegate = self
tableView.register(
CustomCell.self,
forCellReuseIdentifier: CustomCell.identifier
)
title = "Pantalla principal"
}
Aquí se crea una viewModel, se inicializa el data source con arrays y se suscribe a notificaciones que deben estar activas durante toda la vida del controlador. Por ejemplo, suscribirse a UIApplication.willEnterForegroundNotification para actualizar datos al volver del fondo es un buen candidato para viewDidLoad. La viewModel en la arquitectura iOS moderna actúa como puente entre el controlador y la lógica de negocio, e inicializarla en viewDidLoad garantiza que los datos estén listos cuando la pantalla aparezca por primera vez.
Presta especial atención a la configuración del data source para tablas y colecciones. Si tu tabla usa UIFetchedResultsController o NSFetchedResultsController con Core Data, inicializa el fetch request y el delegado en viewDidLoad. Esto garantiza que cuando la pantalla aparezca por primera vez, la tabla ya esté poblada con datos sin solicitudes adicionales.
En viewDidLoad se configuran los botones de la NavigationBar, se establece el large title, se añade el search controller y se definen los botones edit/done. Estos elementos rara vez cambian cuando la pantalla se muestra de nuevo, por lo que inicializarlos aquí es óptimo.
No todas las operaciones son apropiadas en viewDidLoad. Algunas acciones colocadas en este método provocan un consumo excesivo de memoria, un comportamiento incorrecto o errores al volver a mostrar la pantalla.
Evita iniciar solicitudes de red cuyo resultado solo afecte a la UI. Si la solicitud se completa antes de que aparezca la pantalla, el usuario no verá el resultado, y si se completa después — los datos pueden estar desactualizados. Inicia la carga en viewDidLoad, pero actualiza la UI en viewWillAppear.
No realices operaciones en viewDidLoad que dependan del tamaño y la posición de la View. En el momento de la llamada, Auto Layout no ha completado sus pasos y el frame puede no ser definitivo. Para cálculos, usa viewDidLayoutSubviews o sobrescribe updateViewConstraints.
No te suscribas a notificaciones que solo son relevantes cuando la pantalla es visible. Notificaciones de teclado, notificaciones de cambio de contenido de controladores hijos — suscríbete a ellas en viewWillAppear y cancela la suscripción en viewDidDisappear para evitar llamadas innecesarias y fugas.
No llames a métodos que requieran una pantalla visible. Por ejemplo, intentar mostrar un UIAlertController desde viewDidLoad provocará un error porque la View del controlador aún no se ha añadido a la jerarquía de ventanas. Cualquier operación de UI que dependa de la ventana o presentedViewController debe realizarse solo después de que la pantalla aparezca.
No inicialices recursos pesados innecesariamente. Si la pantalla se muestra raramente o los datos no se muestran inmediatamente, aplaza la creación de objetos que consumen muchos recursos hasta que realmente se necesiten. La inicialización perezosa de propiedades en Swift es un mecanismo incorporado para resolver este problema: una propiedad con el modificador lazy se creará solo en el primer acceso, ahorrando memoria y acelerando la carga de la pantalla.
No uses viewDidLoad para operaciones que deben ejecutarse cada vez que aparece la pantalla. Este es el error más fundamental: los desarrolladores principiantes suelen colocar la lógica de actualización de datos en viewDidLoad y se sorprenden de que al volver de otra pantalla la tabla no se recargue. Si una operación debe repetirse en cada visualización — usa viewWillAppear. Si debe ejecutarse una vez durante la vida del controlador — usa viewDidLoad. Recuerda esta sencilla regla para evitar la mayoría de los problemas con el ciclo de vida de UIViewController.
Veamos tres ejemplos prácticos que demuestran el uso correcto de viewDidLoad en proyectos reales. Cada ejemplo resuelve una tarea específica de configuración de pantalla.
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 = "¡Hola, mundo!"
label.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(label)
NSLayoutConstraint.activate([
label.centerXAnchor.constraint(equalTo: view.centerXAnchor),
label.centerYAnchor.constraint(equalTo: view.centerYAnchor)
])
}
En viewDidLoad también se configuran los elementos que se muestran cuando no hay datos: estado vacío, loader, placeholder. Estos componentes se crean una vez y se reutilizan cada vez que aparece la pantalla. Ocultar o mostrar estos elementos se gestiona en viewWillAppear según los datos actuales.
override func viewDidLoad() {
super.viewDidLoad()
emptyStateLabel = UILabel()
emptyStateLabel.text = "Sin datos"
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()
}
Preguntas frecuentes
En condiciones normales, no — UIKit llama a viewDidLoad una vez después de cargar la View en memoria. Si el controlador se destruye y se crea de nuevo, viewDidLoad se ejecutará para la nueva instancia.
Sí, absolutamente. Llamar a super.viewDidLoad garantiza que UIKit realice la configuración interna necesaria para que el Lifecycle funcione correctamente. Siempre llama a super al principio del método.
viewDidLoad se llama una vez al cargar la View. viewWillAppear se llama cada vez antes de que aparezca la pantalla. El primero es para configuración única, el segundo para actualizar datos y estado.
Las operaciones síncronas pesadas en viewDidLoad bloquean el hilo principal y retrasan la aparición de la pantalla. Las cargas asíncronas son aceptables, pero al actualizar la UI al completarse hay que tener en cuenta que la pantalla puede estar ya oculta.
No se puede llamar a viewDidLoad directamente — UIKit lo llama. Para forzar la carga de la View, accede a la propiedad controller.view. Esto activará loadView y viewDidLoad automáticamente.
Resumen
Desarrollaremos una aplicación móvil llave en mano
IT Sectr crea aplicaciones para iOS y Android para startups y empresas desde 2017. Le asesoraremos y le propondremos la mejor solución.
Lea también