ViewController Lifecycle en iOS: conceptos clave, etapas y métodos

Autor: IT Sectr Publicado: 2026-03-05 Tiempo de lectura: 9 min

ViewController Lifecycle es la secuencia de métodos que UIKit llama automáticamente al gestionar pantallas en iOS. Según la Documentación de Apple, cada UIViewController pasa por un conjunto predecible de estados: desde la creación de la View hasta su aparición y desaparición. Comprender el orden y el propósito de estos métodos es una condición necesaria para el funcionamiento estable de una app iOS.

Puntos clave

  • ViewController Lifecycle consta de seis métodos de UIViewController llamados por UIKit en un orden estricto
  • loadView crea la jerarquía de View si no usas Storyboard
  • viewDidLoad se llama una vez y es adecuado para la configuración inicial de la pantalla
  • viewWillAppear y viewDidAppear se activan en cada aparición
  • viewWillDisappear y viewDidDisappear — para guardar estado y limpiar

Qué es ViewController Lifecycle

ViewController Lifecycle es un conjunto de métodos que UIViewController recibe de UIKit a lo largo de su existencia. Cada pantalla en una app iOS pasa secuencialmente por las etapas de creación, carga de View, aparición en pantalla, desaparición y liberación de memoria. UIKit llama automáticamente los métodos correspondientes en cada etapa, y el desarrollador los sobrescribe para agregar su lógica.

La arquitectura de UIViewController es fundamental para UIKit y sigue siendo relevante incluso en la era de SwiftUI — muchos proyectos siguen usando el enfoque clásico o una arquitectura híbrida. Comprender el Lifecycle permite predecir en qué momento las subviews están disponibles, cuándo es seguro modificar el layout y qué operaciones realizar al aparecer o desaparecer la pantalla.

Cada método del ciclo de vida tiene un propósito específico: algunos se llaman una sola vez durante toda la vida del controlador, otros — en cada aparición o desaparición. Mezclar la lógica entre métodos conduce a errores difíciles de encontrar: fugas de memoria, actualizaciones incorrectas de datos y solicitudes de red innecesarias.

Ciclo completo de métodos de UIViewController

Seis métodos forman el ciclo de vida completo de UIViewController. El orden de llamada es fijo y no depende del método de navegación — push, present o unwind segue siguen el mismo programa.

loadView — creación de la View raíz

loadView es el primer método del ciclo, llamado cuando la View del controlador aún no existe. Si usas Storyboard, UIKit carga automáticamente la View desde el archivo xib. Al crear la interfaz mediante programación, sobrescribes este método asignando la View raíz manualmente. En la mayoría de los proyectos, loadView no se toca — el trabajo se hace en viewDidLoad.

Sobrescribir loadView solo es necesario en casos específicos: cuando toda la interfaz se crea en código sin Storyboard, o cuando la View raíz debe ser de una clase no estándar. Apple recomienda no llamar a super.loadView al sobrescribir — asumes toda la responsabilidad de crear la View.

swift
override func loadView() {
    view = UIView()
    view.backgroundColor = .white
}

viewDidLoad — inicialización única

viewDidLoad es el método más utilizado del ciclo. Se llama una vez después de que la View se carga en memoria pero aún no se muestra en pantalla. Aquí se configuran las subviews, se llenan las tablas con datos, se registran las celdas y se suscriben notificaciones que duran toda la vida del controlador.

Una característica importante: viewDidLoad no se vuelve a llamar cuando la pantalla se muestra nuevamente. Si necesitas actualizar datos cada vez que aparece la pantalla — usa viewWillAppear. Coloca solo operaciones únicas en viewDidLoad que sean necesarias para la configuración básica.

viewWillAppear — preparación antes de mostrar

viewWillAppear se llama cada vez justo antes de que la View se vuelva visible para el usuario. Este método recibe un parámetro animated que indica si la aparición es animada. Aquí se actualizan datos, se recargan tablas, se configura el NavigationBar y se ocultan o muestran elementos según el estado de la aplicación.

Usa viewWillAppear para la sincronización de estado entre pantallas: si el usuario pudo haber cambiado datos en la pantalla anterior, este método es el lugar adecuado para actualizar la interfaz. Cada llamada a viewWillAppear precede a la aparición de la pantalla, incluso al regresar de un controlador hijo.

viewDidAppear — pantalla completamente visible

viewDidAppear notifica que la View ha aparecido completamente en pantalla y todas las animaciones de transición han finalizado. En este punto, la pantalla está lista para la interacción — el usuario ve la interfaz completa y puede interactuar con ella. Este método es adecuado para iniciar animaciones que deben comenzar después de la aparición, iniciar temporizadores y rastrear impresiones de análisis.

A diferencia de viewWillAppear, viewDidAppear garantiza que la pantalla no solo es visible sino que también se ha renderizado por completo. Si inicias una animación en viewWillAppear, es posible que se omitan algunos fotogramas porque UIKit aún no ha completado la transición. Para animaciones suaves, usa viewDidAppear.

viewWillDisappear — preparación para ocultar

viewWillDisappear se llama antes de que la View desaparezca de la pantalla — al hacer la transición a otro controlador, cerrar una ventana modal o suspender la app. Este es el lugar adecuado para guardar el estado, cancelar la suscripción a notificaciones, detener procesos activos y liberar recursos que no se necesitan cuando la pantalla no es visible.

Es importante recordar: viewWillDisappear no garantiza que la View finalmente desaparezca — el gesto puede cancelarse. Por lo tanto, guarda los datos críticos también en viewDidDisappear, que se llama solo después de la desaparición real.

viewDidDisappear — pantalla oculta

viewDidDisappear completa el ciclo de aparición y desaparición. Se llama después de que la View ya está oculta de la pantalla. En este método, se detienen finalmente las animaciones, se eliminan los objetos temporales y se confirma el guardado de datos iniciado en viewWillDisappear.

Este método también precede al deinit del controlador — si tu UIViewController se destruye, viewDidDisappear será el último método del Lifecycle antes de que se llame a deinit. Úsalo para la limpieza final que debe ocurrir antes de que el objeto sea destruido.

Cuándo se llama cada método

La secuencia de llamadas depende de cómo aparece la pantalla: por primera vez, al regresar o cuando se presenta modalmente. Consideremos tres escenarios principales desde la perspectiva de UIKit.

Orden en la primera apertura

Cuando una pantalla aparece por primera vez, UIKit recorre el ciclo completo de creación: se llama a loadView, luego a viewDidLoad, después de lo cual comienza la animación de aparición. Durante la animación, se llama a viewWillAppear, y al finalizar — a viewDidAppear. Este es el único escenario donde todos los métodos desde loadView hasta viewDidAppear se activan secuencialmente.

swift
override func viewDidLoad() {
    super.viewDidLoad()
    print("viewDidLoad — View cargada en memoria")
}

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    print("viewWillAppear — Próximo a aparecer")
}

override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)
    print("viewDidAppear — Pantalla completamente visible")
}

Orden al regresar

Cuando el usuario regresa a una pantalla anterior, UIKit no vuelve a llamar a viewDidLoad — la View ya está cargada en memoria. En su lugar, solo se llaman viewWillAppear y viewDidAppear en la pantalla de retorno, y en la actual — viewWillDisappear y viewDidDisappear. loadView y viewDidLoad se omiten ya que la pantalla ya existe en la pila de navegación.

Casos especiales con present y dismiss

La presentación modal sigue las mismas reglas: el nuevo controlador pasa por el ciclo completo en la primera aparición, mientras que el actual recibe viewWillDisappear y viewDidDisappear. Al hacer dismiss, el orden se invierte: el controlador que regresa obtiene viewWillAppear y viewDidAppear nuevamente, mientras que el descartado recibe los métodos finales. Este comportamiento es uniforme para todos los tipos de transición en UIKit.

Escenarios prácticos de uso

Veamos cuatro escenarios clave donde la comprensión del Lifecycle impacta directamente en la calidad del código y la experiencia del usuario. Para cada escenario, proporcionamos un ejemplo con recomendaciones.

Inicialización de datos en viewDidLoad

viewDidLoad es el lugar para la configuración inicial que no depende de la visibilidad de la pantalla. Aquí se configura el collectionView, se registran archivos nib para las celdas, se crean fuentes de datos y layouts. Si estás cargando datos de la red, en viewDidLoad es mejor solo iniciar la solicitud y actualizar la UI en viewWillAppear cuando la pantalla esté lista para mostrarse.

swift
override func viewDidLoad() {
    super.viewDidLoad()
    tableView.register(
        MyCell.self,
        forCellReuseIdentifier: MyCell.identifier
    )
    viewModel.loadInitialData()
}

Actualización de contenido en viewWillAppear

Usa viewWillAppear para la sincronización de datos cada vez que aparece la pantalla. Por ejemplo, si el usuario pudo haber cambiado la configuración en la pantalla anterior, aquí se actualizan los valores mostrados, se recarga la tabla y se ajusta el estado del NavigationBar. Esto garantiza que la pantalla siempre muestre datos actualizados en cualquier escenario de navegación.

swift
override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    tableView.reloadData()
    navigationController?.setNavigationBarHidden(false, animated: animated)
}

Analítica y animaciones en viewDidAppear

viewDidAppear es ideal para iniciar animaciones que deben comenzar después de que el usuario haya visto la pantalla. Aquí también se envían eventos de análisis: visualización de pantalla, inicio de onboarding o reproducción de video. Iniciar animaciones antes de que la transición esté completa provoca una interfaz entrecortada — UIKit no tiene tiempo suficiente para preparar una cantidad adecuada de fotogramas.

Guardado de estado en viewWillDisappear

En viewWillDisappear, se guardan borradores, se detienen temporizadores y se cancela la suscripción a NotificationCenter. Este es el último momento en que la pantalla aún es visible y accesible para operaciones que requieren contexto del usuario. Para datos críticos, usa adicionalmente viewDidDisappear como protección contra gestos cancelados.

Errores típicos al trabajar con Lifecycle

El uso incorrecto de los métodos del ciclo de vida es una de las fuentes más frecuentes de errores en apps iOS. Veamos los principales errores que cometen los desarrolladores en diferentes etapas del trabajo con UIViewController.

El primer error — crear subviews en init o loadView al usar Storyboard. Si estás usando Interface Builder, no sobrescribas loadView innecesariamente. Crear una View en loadView cuando existe un storyboard resulta en ignorar el archivo xib y obtener una pantalla vacía.

El segundo error — suscribirse a notificaciones de teclado en viewDidLoad sin cancelar la suscripción. Si te suscribiste a UIResponder.keyboardWillShowNotification pero no cancelaste la suscripción al ocultar la pantalla, el bloque se seguirá llamando incluso después del deinit del controlador — esto es una fuga de memoria con posible bloqueo de la app.

El tercer error — temporizadores y solicitudes de red iniciados antes de que aparezca la pantalla. Cargar imágenes o realizar animaciones cuando la View aún no es visible es un desperdicio de recursos. Mueve las actualizaciones visuales a viewWillAppear o viewDidAppear.

El cuarto error — guardar datos solo en viewWillDisappear. Con un gesto de pop interactivo, el usuario puede comenzar un deslizamiento y cancelarlo — el método se llamó pero la pantalla no desapareció. Duplica el guardado crítico en viewDidDisappear o en el manejador applicationDidEnterBackground.

Preguntas frecuentes

¿Cuántas veces se llama a viewDidLoad durante la vida del controlador?

Una vez — después de cargar la View en memoria. Cuando la pantalla aparece nuevamente, viewDidLoad no se llama. Si necesitas recrear la View, el controlador debe ser destruido y creado de nuevo.

¿Qué pasa si no llamas a super en viewDidLoad?

UIKit requiere llamar a super.viewDidLoad para que el ciclo de vida funcione correctamente. Sin ello, pueden ocurrir problemas con las actualizaciones de layout y el manejo de transiciones. Siempre llama a super como primera acción dentro del método.

¿Puedo usar Storyboard y loadView programático al mismo tiempo?

No se recomienda. Si el controlador se inicializa desde Storyboard, UIKit carga automáticamente la View desde el xib. Sobrescribir loadView cancela este proceso y tu storyboard será ignorado.

¿Cómo cancelar la suscripción correctamente de NotificationCenter?

Suscríbete en viewDidLoad o viewWillAppear, y cancela la suscripción en viewWillDisappear o viewDidDisappear, usando una referencia débil a self para evitar fugas de memoria con closures.

¿Por qué no se llama a viewDidDisappear al forzar el cierre?

El forzar el cierre mata el proceso abruptamente — UIKit no tiene tiempo para llamar a los métodos del Lifecycle. Para guardar datos, usa la notificación UIApplication.willTerminateNotification en AppDelegate.

Resumen

  • ViewController Lifecycle consta de seis métodos llamados por UIKit en un orden fijo
  • loadView y viewDidLoad se activan una vez al crear el controlador
  • viewWillAppear y viewDidAppear se llaman en cada aparición de la pantalla
  • viewWillDisappear y viewDidDisappear — en cada desaparición
  • Cada método tiene un propósito específico — mezclar la lógica provoca errores
  • Las suscripciones a notificaciones siempre deben equilibrarse con la cancelación en el método correspondiente
  • Usa viewDidAppear para animaciones y análisis, y viewWillDisappear para guardar estado

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.

Discutir el proyecto

Lea también