¿Cuál es la diferencia entre -[UIViewController viewWillAppear:]
y -[UIViewController viewDidAppear:]
?
¿Cuál es la diferencia entre -[UIViewController viewWillAppear:]
y -[UIViewController viewDidAppear:]
?
Respuestas:
En general, esto es lo que hago:
1) ViewDidLoad : cada vez que agrego controles a una vista que debería aparecer junto con la vista, de inmediato, lo pongo en el método ViewDidLoad. Básicamente, este método se llama cada vez que la vista se carga en la memoria. Entonces, por ejemplo, si mi vista es un formulario con 3 etiquetas, agregaría las etiquetas aquí; la vista nunca existirá sin esas formas.
2) ViewWillAppear : utilizo ViewWillAppear generalmente solo para actualizar los datos en el formulario. Entonces, para el ejemplo anterior, usaría esto para cargar realmente los datos de mi dominio en el formulario. La creación de UIViews es bastante costosa, y debe evitar lo más posible hacerlo con el método ViewWillAppear, porque cuando se llama, significa que el iPhone ya está listo para mostrar la UIView al usuario, y cualquier cosa pesada que haga aquí impactará en el rendimiento de una manera muy visible (como retrasar las animaciones, etc.).
3) ViewDidAppear : Finalmente, utilizo ViewDidAppear para iniciar nuevos subprocesos a cosas que llevarían mucho tiempo ejecutar, como por ejemplo hacer una llamada de servicio web para obtener datos adicionales para el formulario anterior. Lo bueno es que la vista ya existe y se está mostrando al usuario, puede mostrar un mensaje agradable de "Espera" al usuario mientras obtiene los datos.
viewWillAppear
? ¿Te refieres a descargar a través de la red? ¿Pero también sugieres descargar cosas en viewDidAppear
?
ViewDidAppear
, fácilmente confundirás al usuario con la interfaz de usuario :)
viewDidLoad === >>> Pon tu código de inicialización aquí. No coloque datos dinámicos que puedan cambiar durante el ciclo de vida de la vista. Entonces, si está extrayendo datos de los datos centrales, no desea hacerlo aquí si esto podría cambiar durante la vida de la vista. Por ejemplo: digamos que tiene un controlador de pestaña. Cambia de tab1 a tab2 y cambia algo en el modelo en tab2. Si vuelve a tab1 y su código de modelo se realizó en viewDidLoad, esto no se actualizará (suponiendo que no esté utilizando KVO o NSFetchedResultsController, etc.).
viewWillAppear === >>> Esto se llama cada vez que la vista está a punto de aparecer, ya sea que la vista ya esté en la memoria o no. Pon tu código dinámico aquí, como la lógica del modelo.
viewDidAppear === >>> Ponga aquí operaciones costosas que solo desea hacer si está seguro de que la vista está en pantalla, como llamadas de red.
Aviso: si su aplicación está en segundo plano y vuelve al primer plano, debe manejar esto usando NSNotificationCenter. Escribí el código para eso en los comentarios a continuación. Puede pensar que viewWillAppear / viewDidAppear se disparará. Pon un punto de quiebre allí y pruébalo. No dispara Por lo tanto, si algo ha cambiado para su aplicación mientras estaba en segundo plano, deberá actualizarla mediante notificaciones.
Se viewWillAppear
llama al método antes de cargar la vista real.
Se viewDidAppear
llama al método cuando la vista ya está cargada y desea mostrar algo.
viewWillAppear:
■ Llamado antes de que la vista se agregue a la jerarquía de vistas de Windows
■ Llamado antes de [vc.view layoutSubviews] (si es necesario)
viewDidAppear :
■ Llamado después de que la vista se agrega a la jerarquía de vistas
■ Llamado después de [vc.view layoutSubviews] (si necesario)
Algunas observaciones:
Se viewDidLoad
llama al método cuando la vista se instancia por primera vez. IBOutlet
las referencias están conectadas para cuando esto se ha llamado, pero no antes. Sin frame
embargo, es posible que no se haya establecido el punto de vista para el momento en que se haya llamado. Este es un gran lugar para agregar / configurar subvistas y sus restricciones asociadas. Pero si está realizando una configuración manual de frame
valores en función de las dimensiones de la vista principal, la configuración de esos marcos debe diferirse hasta viewWillAppear
o viewDidLayoutSubviews
.
Se viewWillAppear
llama al método cuando la presentación de la vista en la jerarquía de vistas está por comenzar. Notablemente, esto se llama al comienzo de la animación (si la hay) de la presentación de la vista. Su compañero, viewWillDisappear
obviamente , se llama cuando comienza la transición lejos de esta vista.
Se viewDidAppear
llama al método cuando finaliza la presentación de la vista, especialmente cuando finaliza cualquiera de las animaciones asociadas. Su compañero, viewDidDisappear
obviamente , se llama cuando la transición se aleja de esta vista.
Dos advertencias importantes:
viewDidLoad
se llama una vez y solo una vez, cuando la vista se instancia por primera vez. Por otro lado, viewWillAppear
y viewDidAppear
se llamará no solo cuando la vista se presenta por primera vez, sino cada vez que se vuelva a presentar la misma vista en cuestión. Por ejemplo, cuando presenta una vista por primera vez, se llamará a estos tres métodos. Si la vista en cuestión presenta posteriormente otra vista que posteriormente se desestimó, el viewWillAppear
y viewDidAppear
, generalmente, se llama de nuevo cuando se añade el punto de vista de que se trate y animado de nuevo en la jerarquía de la vista, pero viewDidLoad
no lo hará. viewDidLoad
solo se llama cuando esta instancia particular se crea por primera vez.
Por lo tanto, si desea hacer algo cada vez que vuelve a aparecer una vista (por ejemplo, lo descarta o vuelve a aparecer), hágalo en viewWillAppear
o viewDidAppear
. Si desea que solo suceda cuando la vista se instancia por primera vez, hágalo viewDidLoad
.
El llamado de viewWillAppear
no garantiza que la transición a esa vista se completará nunca. Notablemente, si está utilizando una transición interactiva que es impulsada por la entrada del usuario en tiempo real, pero esa transición interactiva puede cancelarse. Es decir, solo porque viewWillAppear
se llama, no significa que viewDidAppear
se llamará. Generalmente lo es, pero si el gesto interactivo se cancela, no lo hará (porque la transición nunca terminó).
En WWDC 2013, en el contexto de las transiciones interactivas, un presentador bromeó diciendo que deberían cambiar el nombre viewWillAppear
a " viewMightAppear
, o viewWillProbablyAppear
, o iReallyWishThisViewWouldAppear
".
Un ejemplo de un gesto interactivo incorporado es cuando se usa UINavigationController
ay "desliza el dedo desde el borde izquierdo" para iniciar un pop de la vista. Se viewWillAppear
llamará a la vista a la que está apareciendo, pero si cancela ese "deslizar desde el borde izquierdo" para volver a la vista desde la que inició este gesto de pop, se cancela el pop y viewDidAppear
la vista que comenzó a pop back to nunca será llamado.
El efecto neto de esto es que debe tener cuidado de no escribir código que suponga que cada llamada a viewWillAppear
será seguida eventualmente por una llamada a viewDidAppear
. Si se cancela la transición, este no será el caso.
1) ViewWillAppear : la vista cargada realmente en la memoria, llamada una vez en el controlador de vista y tenía su marco, pero aún no se le apareció al usuario
2) ViewDidAppear : el controlador agregado a la jerarquía de vistas, por lo que podría presentar al siguiente controlador, también, la vista diseñó las subvistas
Lo primero sucede antes de que aparezca la vista y lo segundo sucede después.
Para resumir:
-viewWillAppear -> actualizar datos (recargar datos desde una vista de tabla)
-viewDidAppear -> operaciones costosas (llamada API con un buen progreso hud!)
Usecase , es decir, ¿ cuándo debo usar cuál?
viewDidLoad
- cuando las etiquetas, los botones (es decir, cualquier control / subvista) están conectados al archivo de interfaz de la Vista y si desea cargar todo esto al mismo tiempo que la Vista del Controlador de la Vista, y si desea cargar esto en la memoria una vez y estar hecho con eso
viewWillAppear
- por ejemplo, desea cambiar el color de fondo de la vista cada vez que viewController aparece en la pantalla. O de manera más realista si desea el color de fondo DarkMode en la noche del día y el color claro de la vista de fondo durante el día, busque este código enviewWillAppear
Otro buen caso de uso aquí https://stackoverflow.com/a/39395865/5438240
También tenga en cuenta que, si está utilizando una pila de Navegación ( UINavigationController
), el viewController que está a punto de aparecer tiene el viewWillDisappear()
llamado, y el ViewController que luego estará en la parte superior de la pila habrá viewWillAppear()
llamado