ciclo de vida viewcontroller ios
Buscando entender el ciclo de vida de iOS UIViewController (12)
A partir de iOS 6 y posteriores. El nuevo diagrama es el siguiente:
¿Podría explicarme la manera correcta de administrar el ciclo de vida de 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
.
Concentrémonos en los métodos, que son responsables UIViewController''s ciclo UIViewController''s vida UIViewController''s :
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
Para obtener más información, eche un vistazo a UIViewController''s .
El ciclo de vida de UIViewController está diagramado aquí:
http://rdkw.wordpress.com/2013/02/24/ios-uiviewcontroller-lifecycle/
Esto es para las últimas versiones de iOS (modificadas 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 explicarte todas esas etapas.
1. loadView
Este evento crea la vista que el controlador maneja. Solo se llama cuando el controlador de vista se crea mediante programación. 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 no se ha configurado aún la vista de viewController
actual, este método cargará la vista, pero recuerde que 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 va a utilizar el controlador de vista.
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. Ver Aparecerá
Este evento notifica al viewController
cada vez que la vista aparece en la pantalla. En este paso, la vista tiene límites que están 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 Auto Layout, probablemente desee 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 después de que se hayan establecido. 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 viewDidAppear
después de que la vista se presente en la pantalla. Lo que lo convierte en 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 viewWillDisappear
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 cualquier persona puede abordar, ya que este evento se dispara justo después de que la vista de viewController
presentada haya desaparecido, descartado, cubierto u oculto.
Called after the view was dismissed, covered or otherwise hidden.
Default does nothing
Ahora, según Apple, cuando esté implementando estos métodos, debe recordar llamar a la super
implementación 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 programatically.
Espero que esto haya ayudado. Gracias.
ACTUALIZACIÓN : como @ThomasW señaló dentro de la vista de comentarios, viewWillLayoutSubviews
y viewDidLayoutSubviews
también se viewDidLayoutSubviews
en otros momentos cuando se carguen subvistas de la vista principal, por ejemplo, cuando se carguen celdas de una vista de tabla o de colección.
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 varios métodos de devolución de llamada ''will'' y ''did''
Hay mucha información obsoleta e incompleta aquí. Solo para iOS 6 y más reciente :
-
loadView
[a] -
viewDidLoad
[a] -
viewWillAppear
-
viewWillLayoutSubviews
es la primera vez que se finalizan los límites -
viewDidLayoutSubviews
-
viewDidAppear
-
*
viewWillLayoutSubviews
[b] -
*
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 se llaman una vez por instancia de controlador de vista.
(b) Puede ser llamado 0 o más veces adicionales.
La respuesta de Haider es correcta para pre-iOS 6. Sin embargo, a partir de iOS 6, viewDidUnload y viewWillUnload nunca se llaman. El estado de los docs : "Las vistas ya no se purgan en condiciones de poca memoria, por lo que este método nunca se llama".
Los métodos viewWillLayoutSubviews
y viewDidLayoutSubviews
no se mencionan en los diagramas, pero estos se llaman entre viewWillAppear
y viewDidAppear
. Se les puede llamar varias veces.
Según los docs Apple
viewDidLoad
: se llama cuando la vista de contenido del controlador de vista (la parte superior de su jerarquía de vista) se crea y carga desde un guión gráfico. Utilice este método para realizar cualquier configuración adicional requerida por su controlador de vista.
viewWillAppear
: se llama justo antes de que la vista de contenido del controlador de vista se agregue a la jerarquía de vistas de la aplicación. Utilice este método para activar cualquier operación que deba ocurrir antes de que la vista de contenido se muestre en pantalla
viewDidAppear
: se llama justo después de que la vista de contenido del controlador de vista se haya agregado a la jerarquía de vistas de la aplicación. Utilice este método para activar cualquier operación que deba ocurrir tan pronto como se presente la vista en la pantalla, como recuperar datos o mostrar una animación.
viewWillDisappear
: se llama justo antes de que la vista de contenido del controlador de vista se elimine de la jerarquía de vistas de la aplicación. Utilice este método para realizar tareas de limpieza como confirmar cambios o renunciar al estado del primer respondedor.
viewDidDisappear
: se llama justo después de que la vista de contenido del controlador de vista se haya eliminado de la jerarquía de vistas de la aplicación. Utilice este método para realizar actividades de desmontaje adicionales.
Todos estos comandos son llamados automáticamente en los momentos apropiados por iOS cuando carga / presenta / oculta el controlador de vista. Es importante tener en cuenta que estos métodos se adjuntan a UIViewController
y no a UIView
s. No obtendrás ninguna de estas funciones con solo usar UIView
.
Hay una gran documentación en el sitio de Apple here . Poner simplemente sin embargo:
ViewDidLoad
: se llama cuando crea la clase y carga desde xib. Ideal para la configuración inicial y el trabajo de una sola vez.ViewWillAppear
- Llamado justo antes de que aparezca su vista, es bueno para ocultar / mostrar campos o cualquier operación que desee que ocurra cada vez que se vea la vista. Debido a que es posible que vaya y venga de una vista a otra, esto se activará cada vez que su vista aparezca en la pantalla.ViewDidAppear
- Llamado después de que aparezca la vista - excelente lugar para comenzar una animación o la carga de datos externos desde una API.ViewWillDisappear
/DidDisappear
- La misma idea queViewWillAppear
/ViewDidAppear
.ViewDidUnload
/ViewDidDispose
: en Objective C, aquí es donde realiza la limpieza y el lanzamiento de las cosas, pero esto se maneja automáticamente, por lo que no es mucho lo que debe hacer aquí.
iOS 10,11 (Swift 3.1, Swift 4.0)
Según UIViewController
en los desarrolladores de UIKit
,
1. loadView ()
Aquí es donde las subclases deben crear su jerarquía de vista personalizada si no están usando una nib . Nunca debe ser llamado directamente.
2. loadViewIfNeeded ()
Carga la vista del controlador de vista si aún no se ha configurado.
3. viewDidLoad ()
Llamado después de que la vista ha sido cargada. Para los controladores de vista creados en código, esto es después de -loadView. Para los controladores de vista no archivados de una plumilla, esto ocurre después de que se establece la vista.
4. viewWillAppear (_ animated: Bool)
Llamado cuando la vista está a punto de hacerse visible. Por defecto no hace nada
5. viewWillLayoutSubviews ()
Se llama justo después de que se invoque el método layoutSubviews de view view. Las subclases pueden implementarse según sea necesario.
6. viewDidLayoutSubviews ()
Se llama cuando el tamaño, la posición y las restricciones se aplican a todos los objetos.
7. viewDidAppear (_ animated: Bool)
Se llama cuando la vista ha pasado completamente a la pantalla. Por defecto no hace nada
8. viewWillDisappear (_ animated: Bool)
Se invoca cuando la vista se descarta, se cubre o se oculta de otro modo. Por defecto no hace nada
9. viewDidDisappear (_ animated: Bool )
Llamado después de que la vista fue descartada, cubierta u oculta de otro modo. Por defecto no hace nada
10. viewWillTransition (a tamaño: CGSize, con coordinador: UIViewControllerTransitionCoordinator)
Llamado cuando la vista está en transición.
11. willMove (toParentViewController parent: UIViewController?)
12. didMove (toParentViewController padre: UIViewController?)
Estos dos métodos son públicos para que las subclases de contenedor llamen al realizar la transición entre controladores secundarios. Si se anulan, las anulaciones deben asegurarse de llamar al super.
El argumento principal en estos dos métodos es nulo cuando un hijo se está eliminando de su padre; de lo contrario, es igual al nuevo controlador de vista principal.
13. didReceiveMemoryWarning ()
Se llama cuando la aplicación principal recibe una advertencia de memoria. En iOS 6.0 ya no borrará la vista de forma predeterminada.
init(coder:)
Cuando creas las vistas de tu aplicación en un Guión gráfico, init(coder:)
es el método al que se llama para crear una instancia del controlador de vista 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 llame a este método, es probable que su vista se muestre en un futuro próximo (o en un futuro muy 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 poner las cosas en orden, pero no demasiado aquí o perderá el poder de procesamiento. En este método, puede crear instancias de dependencias, incluidas subvistas que agregará a su vista mediante programació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 solo una vez durante la vida del objeto controlador de vista. Es un excelente lugar para realizar cualquier configuración de inicio o configuración de vista que no haya hecho en el Guión gráfico. Quizás desee agregar subvistas o restricciones de diseño automático programáticamente; si es así, este es un gran lugar para hacer cualquiera de esas. Tenga en cuenta que el hecho de que la vista se haya cargado en la memoria no significa necesariamente que se vaya a mostrar pronto, por lo tanto, querrá ver 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. Por lo general, llamo super al comienzo de la implementación.
viewWillAppear(_:)
Siempre se llama después de viewDidLoad
(por razones obvias, si lo piensa bien), y justo antes de que la vista aparezca en la pantalla para el usuario, se llama viewWillAppear
. Esto le da la oportunidad de realizar una configuración de visualización de última hora, iniciar una solicitud de red (por supuesto, en otra clase) o actualizar la pantalla. A diferencia de viewDidLoad
, viewWillAppear
se llama la primera vez que se muestra la vista y cuando se vuelve a mostrar, por lo que puede llamarse varias veces durante la vida del objeto controlador de vista. Se llama cuando la vista está a punto de aparecer cuando el usuario toca el botón Atrás, cierra un diálogo modal, cuando se selecciona la pestaña del controlador de vista en un controlador de la barra de pestañas, o por una variedad de otras razones. Asegúrate 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 como viewWillAppear
, este método puede llamarse varias veces durante la vida del objeto controlador de vista. Se llama cuando el usuario se aleja de la pantalla, tal vez para cerrar la pantalla, seleccionar otra pestaña, tocar un botón que muestra una vista modal o navegar más abajo en la jerarquía de navegación. Este es un excelente lugar para ocultar el teclado, guardar el estado y posiblemente cancelar los temporizadores en ejecución o las 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
.