Buscando entender el ciclo de vida UIViewController de iOS

¿Podría explicarme la forma correcta de administrar el ciclo de vida UIViewController ?

En particular, me gustaría saber cómo usar los ViewDidLoad Initialize , ViewDidLoad , ViewWillAppear , ViewDidAppear , ViewWillDisappear , ViewDidDisappear , ViewDidUnload y Dispose en Mono Touch para una clase UIViewController .

Todos estos comandos son llamados automáticamente en los momentos apropiados por iOS cuando carga / presenta / oculta el controlador de visualización. Es importante tener en cuenta que estos métodos están conectados a UIViewController y no a UIView s. No obtendrá ninguna de estas funciones simplemente usando un UIView .

Hay una gran documentación en el sitio de Apple aquí . Sin embargo, simplemente:

  • ViewDidLoad : se ViewDidLoad cuando se crea la clase y se carga desde xib. Ideal para la configuración inicial y el trabajo de una sola vez.

  • ViewWillAppear : se llama justo antes de que aparezca su vista, es bueno para ocultar / mostrar campos o cualquier operación que quiera que ocurra cada vez antes de que la vista sea visible. Debido a que puede estar yendo y viniendo entre las vistas, se invocará cada vez que su vista esté a punto de aparecer en la pantalla.

  • ViewDidAppear : se lo llama cuando aparece la vista, es un excelente lugar para iniciar animaciones o cargar datos externos desde una API.

  • ViewWillDisappear / DidDisappear : la misma idea que ViewWillAppear / ViewDidAppear .

  • ViewDidUnload / ViewDidDispose – En Objective C, aquí es donde haces tu limpieza y lanzamiento de cosas, pero esto se maneja automáticamente, por lo que no hay mucho que realmente necesites hacer aquí.

El ciclo de vida de UIViewController está diagtwigdo aquí:

http://rdkw.wordpress.com/2013/02/24/ios-uiviewcontroller-lifecycle/

El ciclo de vida de un controlador de vista, diagramado

Esto es para las últimas versiones de iOS (Modificado con Xcode 9.3, Swift 4.1 ). A continuación se muestran todas las etapas que completan el ciclo de vida de un UIViewController .

loadView ()

loadViewIfNeeded ()

viewDidLoad ()

viewWillAppear (_ animated: Bool)

viewWillLayoutSubviews ()

viewDidLayoutSubviews ()

viewDidAppear (_ animated: Bool)

viewWillDisappear (_ animated: Bool)

viewDidDisappear (_ animated: Bool)

Déjame explicar todas esas etapas.

1. loadView

Este evento crea la vista que administra el controlador. Solo se llama cuando el controlador de vista se crea programáticamente. Esto lo convierte en un buen lugar para crear sus vistas en código.

 This is where subclasses should create their custom view hierarchy if they aren't using a nib. Should never be called directly. 

2. loadViewIfNeeded

Si en el caso de que la vista del viewController actual no se haya configurado aún, este método cargará la vista, pero recuerde, esto solo está disponible en iOS> = 9.0. Entonces, si está soportando iOS <9.0, entonces no espere que aparezca en la imagen.

 Loads the view controller's view if it has not already been set. 

3. viewDidLoad

El evento viewDidLoad solo se viewDidLoad cuando la vista se crea y se carga en la memoria, pero los límites de la vista aún no están definidos. Este es un buen lugar para inicializar los objetos que el controlador de vista va a usar.

 Called after the view has been loaded. For view controllers created in code, this is after -loadView. For view controllers unarchived from a nib, this is after the view is set. 

4. viewWillAppear

Este evento notifica a viewController cada vez que aparece la vista en la pantalla. En este paso, la vista tiene límites definidos pero la orientación no está establecida.

 Called when the view is about to made visible. Default does nothing. 

5. viewWillLayoutSubviews

Este es el primer paso en el ciclo de vida donde se finalizan los límites. Si no está utilizando restricciones o diseño automático, probablemente quiera actualizar las subvistas aquí. Esto solo está disponible en iOS> = 5.0. Entonces, si está soportando iOS <5.0, entonces no espere que aparezca en la imagen.

 Called just before the view controller's view's layoutSubviews method is invoked. Subclasses can implement as necessary. The default is a nop. 

6. viewDidLayoutSubviews

Este evento notifica al controlador de vista que las subvistas se han configurado. Es un buen lugar para realizar cambios en las subvistas una vez configuradas. Esto solo está disponible en iOS> = 5.0. Entonces, si está soportando iOS <5.0, entonces no espere que aparezca en la imagen.

 Called just after the view controller's view's layoutSubviews method is invoked. Subclasses can implement as necessary. The default is a nop. 

7. viewDidAppear

El evento viewDidAppear se dispara después de que la vista se presenta en la pantalla. Lo que lo hace un buen lugar para obtener datos de un servicio o base de datos back-end.

 Called when the view has been fully transitioned onto the screen. Default does nothing 

8. viewWillDisappear

El evento viewWillDisappear se dispara cuando la vista del viewController presentado está a punto de desaparecer, descartar, cubrir u ocultar detrás de otro viewController . Este es un buen lugar donde puede restringir sus llamadas de red, invalidar el temporizador o liberar objetos que están vinculados a ese viewController .

 Called when the view is dismissed, covered or otherwise hidden. 

9. viewDidDisappear

Este es el último paso del ciclo de vida que cualquiera puede abordar ya que este evento se dispara justo después de que la vista del viewController presentado haya desaparecido, descartado, cubierto u ocultado.

 Called after the view was dismissed, covered or otherwise hidden. Default does nothing 

Ahora, según Apple, cuando implemente estos métodos, recuerde llamar a la implementación super de ese método específico.

 If you subclass UIViewController, you must call the super implementation of this method, even if you aren't using a NIB. (As a convenience, the default init method will do this for you, and specify nil for both of this methods arguments.) In the specified NIB, the File's Owner proxy should have its class set to your view controller subclass, with the view outlet connected to the main view. If you invoke this method with a nil nib name, then this class' -loadView method will attempt to load a NIB whose name is the same as your view controller's class. If no such NIB in fact exists then you must either call -setView: before -view is invoked, or override the -loadView method to set up your views progtwigtically. 

Espero que esto haya ayudado. Gracias.

ACTUALIZACIÓN : como @ThomasW señaló dentro del comentario viewWillLayoutSubviews y viewDidLayoutSubviews también se viewDidLayoutSubviews en otro momento cuando se carguen las subvistas de la vista principal, por ejemplo, cuando se carguen celdas de una vista de tabla o de colección.

iOS 10,11 (Swift 3.1, Swift 4.0)

De acuerdo con UIViewController en los desarrolladores de UIKit ,

1. loadView ()

Aquí es donde las subclases deberían crear su jerarquía de vista personalizada si no están usando un plumín . Nunca debe ser llamado directamente.

2. loadViewIfNeeded ()

Carga la vista del controlador de vista si aún no se ha configurado.

3. viewDidLoad ()

Se invoca después de que la vista se ha cargado. Para los controladores de vista creados en código, esto es after -loadView. Para los controladores de vista desarchivados de una plumilla, esto es después de que se establece la vista.

4. viewWillAppear (_ animated: Bool)

Se llama cuando la vista está a punto de hacerse visible. El predeterminado no hace nada

5. viewWillLayoutSubviews ()

Se llama justo después de invocar el método layoutSubviews de la vista del controlador de la vista. Las subclases pueden implementarse según sea necesario.

6. viewDidLayoutSubviews ()

Se invoca cuando el tamaño, la posición y las restricciones se aplican a todos los objetos.

7. viewDidAppear (_ animated: Bool)

Se invoca cuando la vista se ha transferido por completo a la pantalla. El predeterminado no hace nada

8. viewWillDisappear (_ animación: Bool)

Se invoca cuando la vista se descarta, se cubre o se oculta de alguna otra manera. El predeterminado no hace nada

9. viewDidDisappear (_ animated: Bool )

Invocado después de que la vista fue descartada, cubierta o escondida. El predeterminado no hace nada

10. viewWillTransition (a tamaño: CGSize, con el coordinador: UIViewControllerTransitionCoordinator)

Se llama cuando la vista es Transición.

11. willMove (toParentViewController parent: UIViewController?)

12. didMove (toParentViewController parent: UIViewController?)

Estos dos métodos son públicos para que las subclases de contenedor llamen cuando se realiza la transición entre los controladores secundarios. Si se anulan, las anulaciones deben garantizar llamar al súper.

El argumento principal en ambos métodos es nulo cuando un hijo se elimina de su padre; de lo contrario, es igual al nuevo controlador de vista principal.

13. didReceiveMemoryWarning ()

Se invoca cuando la aplicación principal recibe una advertencia de memoria. En iOS 6.0 ya no borrará la vista de forma predeterminada.

A partir de iOS 6 en adelante. El nuevo diagtwig es el siguiente:

enter image description here

Los métodos viewWillLayoutSubviews y viewDidLayoutSubviews no se mencionan en los diagtwigs, pero se llaman entre viewWillAppear y viewDidAppear . Se pueden llamar varias veces.

La respuesta de Haider es correcta para pre-iOS 6. Sin embargo, a partir de iOS 6 nunca se llama a viewDidUnload y viewWillUnload. Los documentos indican: “Las vistas ya no se purgan en condiciones de poca memoria y nunca se llama a este método”.

Concentrémonos en los métodos, que son responsables del ciclo de vida de UIViewController :

  • Creación:

    - (void)init

    - (void)initWithNibName:

  • Ver creación:

    - (BOOL)isViewLoaded

    - (void)loadView

    - (void)viewDidLoad

    - (UIView *)initWithFrame:(CGRect)frame

    - (UIView *)initWithCoder:(NSCoder *)coder

  • Manejo del cambio de estado de vista:

    - (void)viewDidLoad

    - (void)viewWillAppear:(BOOL)animated

    - (void)viewDidAppear:(BOOL)animated

    - (void)viewWillDisappear:(BOOL)animated

    - (void)viewDidDisappear:(BOOL)animated

    - (void)viewDidUnload

  • Manejo de advertencia de memoria:

    - (void)didReceiveMemoryWarning

  • Desasignación

    - (void)viewDidUnload

    - (void)dealloc

Diagrama del ciclo de vida de UIViewController

Para obtener más información, consulte UIViewController Class Reference .

Hay una gran cantidad de información obsoleta e incompleta aquí. Solo para iOS 6 y versiones posteriores :

  1. loadView [a]
  2. viewDidLoad [a]
  3. viewWillAppear
  4. viewWillLayoutSubviews es la primera vez que se finalizan los límites
  5. viewDidLayoutSubviews
  6. viewDidAppear
  7. * viewWillLayoutSubviews [b]
  8. * viewDidLayoutSubviews [b]

Notas al pie:

(a) – Si didReceiveMemoryWarning manualmente su vista durante didReceiveMemoryWarning , se loadView viewDidLoad loadView y viewDidLoad . Es decir, de forma predeterminada, loadView y viewDidLoad solo reciben una instancia de controlador de una vez por vista.

(b) Puede llamarse 0 o más veces adicionales.

Explicación de las transiciones de estado en el documento oficial: https://developer.apple.com/library/ios/documentation/uikit/reference/UIViewController_Class/index.html

Esta imagen muestra las transiciones de estado válidas entre los distintos métodos de callback de ‘ver’ y ‘hacer’

Transiciones válidas del estado

 init(coder:) 

Cuando creas las vistas de tu aplicación en un Guión gráfico, init(coder:) es el método que se llama para crear una instancia de tu controlador de visualización y darle vida. El contrato para este método está realmente definido en el protocolo NSCoding, por lo que no lo verá en la documentación de UIViewController .

Cuando se llama a este método, su vista probablemente se muestre en algún momento en el futuro cercano (o en el futuro inmediato), pero en este momento no hay garantía de que realmente se muestre. Así que este podría ser un buen momento para comenzar a ordenar las cosas, pero no hagas demasiado aquí o perderás poder de procesamiento. En este método, puede crear instancias de dependencias, incluidas las subvistas que agregará a su vista mediante progtwigción. Y tenga en cuenta que init(coder:) se llama solo una vez durante la vida del objeto, como lo son todos los métodos init.

 viewDidLoad() 

Llamado después de init(coder:) cuando la vista se carga en la memoria, este método también se llama una sola vez durante la vida del objeto controlador de vista. Es un gran lugar para hacer cualquier inicialización o configuración de vista que no haya hecho en Storyboard. Quizás desee agregar subvistas o restricciones de diseño automático mediante progtwigción, de ser así, este es un excelente lugar para hacer cualquiera de ellas. Tenga en cuenta que el hecho de que la vista se haya cargado en la memoria no significa necesariamente que se mostrará pronto; para eso, deberá consultar viewWillAppear . Ah, y recuerde llamar a super.viewDidLoad() en su implementación para asegurarse de que viewDidLoad de su superclase tenga la oportunidad de hacer su trabajo. Normalmente me llamo súper derecha al comienzo de la implementación.

 viewWillAppear(_:) 

Siempre llamado después de viewDidLoad (por razones obvias, si lo piensa), y justo antes de que la vista aparezca en la pantalla para el usuario, se llama a viewWillAppear . Esto le da la oportunidad de realizar una configuración de vista de último minuto, iniciar una solicitud de red (en otra clase, por supuesto) o actualizar la pantalla. A diferencia de viewDidLoad , viewWillAppear se viewWillAppear la primera vez que se visualiza la vista y cuando la vista se muestra de nuevo, por lo que se puede invocar varias veces durante la vigencia del objeto controlador de vista. Se invoca cuando la vista está a punto de aparecer como resultado de que el usuario toque el botón Atrás, cierre un cuadro de diálogo modal, cuando la pestaña del controlador de la vista esté seleccionada en un controlador de la barra de tabs o por otros motivos. Asegúrese de llamar a super.viewWillAppear() en algún momento de la implementación; generalmente lo hago primero.

 viewWillDisappear(_:) 

Similar a viewWillAppear , este método se llama justo antes de que la vista desaparezca de la pantalla. Y al igual que viewWillAppear , este método se puede llamar varias veces durante la vida del objeto controlador de vista. Se invoca cuando el usuario navega fuera de la pantalla, tal vez ignorando la pantalla, seleccionando otra pestaña, tocando un botón que muestra una vista modal o navegando más abajo en la jerarquía de navegación. Este es un gran lugar para ocultar el teclado, guardar el estado y, posiblemente, cancelar temporizadores en ejecución o solicitudes de red. Al igual que los otros métodos en el ciclo de vida del controlador de vista, asegúrese de llamar a super en algún punto en viewWillDisappear .

Según los documentos de Apple

viewDidLoad : se viewDidLoad cuando se crea y carga la vista de contenido del controlador de vista (la parte superior de su jerarquía de vista) desde un guión gráfico. Use este método para realizar cualquier configuración adicional requerida por su controlador de vista.

viewWillAppear : se llama justo antes de que la vista del contenido del controlador de vista se agregue a la jerarquía de vistas de la aplicación. Utilice este método para desencadenar cualquier operación que deba ocurrir antes de que la vista de contenido se presente en pantalla

viewDidAppear : se llama justo después de que se haya agregado la vista de contenido del controlador de vista a la jerarquía de vistas de la aplicación. Utilice este método para desencadenar cualquier operación que deba realizarse tan pronto como se muestre la vista en pantalla, como recuperar datos o mostrar una animación.

viewWillDisappear : se llama justo antes de que se elimine la vista de contenido del controlador de vista de la jerarquía de vistas de la aplicación. Use este método para realizar tareas de limpieza, como realizar cambios o renunciar al estado del primer respondedor.

viewDidDisappear : se viewDidDisappear justo después de que la vista del contenido del controlador de la vista se eliminó de la jerarquía de vistas de la aplicación. Use este método para realizar actividades de desassembly adicionales.

    Intereting Posts