¿Cuál es la diferencia entre -viewWillAppear: y -viewDidAppear :?

131

¿Cuál es la diferencia entre -[UIViewController viewWillAppear:]y -[UIViewController viewDidAppear:]?

PJR
fuente
1
gracias BoltClock, pero por favor dame un ejemplo de ambos si es posible ..
PJR
3
@BoltClock sería bueno si eso fuera cierto. Supongo que las 15 personas que votaron positivamente leyeron el nombre del método pero nunca lo midieron ... Vine aquí de Google porque esa NO es la diferencia entre ellos
Adam
1
Específicamente: parentView.viewDidAppear se llama MUCHO TIEMPO antes de que Apple realmente muestre parentView ... Apple primero pinta (atómicamente) todas las subvistas ... y si tiene muchas subvistas o complejas, entonces "viewDidAppear" puede llamarse decenas o cientos de milisegundos demasiado pronto :(.
Adam

Respuestas:

292

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.

Chetan Bhalara
fuente
44
Lo sentimos, pero ¿qué quieres decir con "cargar los datos de mi dominio en el formulario" en viewWillAppear? ¿Te refieres a descargar a través de la red? ¿Pero también sugieres descargar cosas en viewDidAppear?
Philip007
1
@ Philip007 Creo que Stack se refiere a este tipo de dominio: en.wikipedia.org/wiki/Domain-specific_modeling . Los datos se cargan desde sus modelos o similares.
dentarg
2
Esta respuesta debería estar en los documentos. Fue realmente útil para aclarar la diferencia entre los tres métodos. ¡Gracias!
GangstaGraham
1
+1 Estaba teniendo un poco de confusión entendiendo la diferencia entre estos tres, pero lo aclaraste más que perfectamente @ChetanBhalara
Chisx
@ChetanBhalara, pero si trabajas mucho ViewDidAppear, fácilmente confundirás al usuario con la interfaz de usuario :)
hqt
46

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.

smileBot
fuente
1
¿Se ejecuta ViewWill o ViewDid cada vez que minimiza la aplicación?
Jeef
2
@Jeef Esta es una excelente pregunta. Ninguno de los dos se ejecuta a menos que el sistema o el usuario eliminen la aplicación mientras está en segundo plano. Lo que debe hacer para recibir una notificación cuando la aplicación no esté minimizada es usar NSNotificationCenter y addObserver para el nombre UIApplicationWillEnterForegroundNotification. El selector debe ser applicationWillEnterForeground: tiene un parámetro NSNotification. Ponga su código en ese método para recargar datos, etc. Lo que puede hacer es crear un método de recarga al que llame desde este método y también verDidAppear si necesitan ser los mismos.
smileBot
2
@Jeef algo como esto: - (vacío) viewDidLoad {[[NSNotificationCenter defaultCenter] addObserver: auto selector: @selector (applicationWillEnterForeground :) nombre: UIApplicationWillEnterForegroundNotification objeto: nil]; } - (nulo) applicationWillEnterForeground: (NSNotification *) notif {// responde aquí con lo que sea}
smileBot
12

Se viewWillAppearllama al método antes de cargar la vista real.

Se viewDidAppearllama al método cuando la vista ya está cargada y desea mostrar algo.

puneet kathuria
fuente
9

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)

andyqee
fuente
7

Algunas observaciones:

  • Se viewDidLoadllama al método cuando la vista se instancia por primera vez. IBOutletlas referencias están conectadas para cuando esto se ha llamado, pero no antes. Sin frameembargo, 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 framevalores en función de las dimensiones de la vista principal, la configuración de esos marcos debe diferirse hasta viewWillAppearo viewDidLayoutSubviews.

  • Se viewWillAppearllama 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, viewWillDisappearobviamente , se llama cuando comienza la transición lejos de esta vista.

  • Se viewDidAppearllama al método cuando finaliza la presentación de la vista, especialmente cuando finaliza cualquiera de las animaciones asociadas. Su compañero, viewDidDisappearobviamente , se llama cuando la transición se aleja de esta vista.

Dos advertencias importantes:

  • viewDidLoadse llama una vez y solo una vez, cuando la vista se instancia por primera vez. Por otro lado, viewWillAppeary viewDidAppearse 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 viewWillAppeary 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 viewDidLoadno lo hará. viewDidLoadsolo 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 viewWillAppearo viewDidAppear. Si desea que solo suceda cuando la vista se instancia por primera vez, hágalo viewDidLoad.

  • El llamado de viewWillAppearno 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 viewWillAppearse llama, no significa que viewDidAppearse 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 viewWillAppeara " viewMightAppear, o viewWillProbablyAppear, o iReallyWishThisViewWouldAppear".

    Un ejemplo de un gesto interactivo incorporado es cuando se usa UINavigationControlleray "desliza el dedo desde el borde izquierdo" para iniciar un pop de la vista. Se viewWillAppearllamará 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 viewDidAppearla 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 viewWillAppearserá seguida eventualmente por una llamada a viewDidAppear. Si se cancela la transición, este no será el caso.

Robar
fuente
5

viewwillappear llamará antes de cargar la vista para que pueda realizar cierta tarea antes de cargar esa vista y viewdidappear llamará después de cargar la vista para que la tarea posterior se realice en ese método

dks1725
fuente
4

Diferencia entre "will" y "did" ... Como su nombre indica, se llama a viewWillAppear antes de que la vista esté a punto de aparecer y viewDidAppear se llama cuando aparece la vista.

Mahesh
fuente
mira la respuesta aceptada hermano, que contiene más de 70 votos a favor. :)
PJR
4

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

Abuzeid Ibrahim
fuente
3

Lo primero sucede antes de que aparezca la vista y lo segundo sucede después.

Marc Abramowitz
fuente
3

Para resumir:

-viewWillAppear -> actualizar datos (recargar datos desde una vista de tabla)

-viewDidAppear -> operaciones costosas (llamada API con un buen progreso hud!)

Nahuel Roldan
fuente
1

Como su nombre indica, viewWillAppearse llama antes de que la vista esté a punto de aparecer y viewDidAppearse llama cuando apareció la vista.

visakh7
fuente
0

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

Naishta
fuente