Quelle est la différence entre -[UIViewController viewWillAppear:]
et -[UIViewController viewDidAppear:]
?
Quelle est la différence entre -[UIViewController viewWillAppear:]
et -[UIViewController viewDidAppear:]
?
Réponses:
En général, voici ce que je fais:
1) ViewDidLoad - Chaque fois que j'ajoute des contrôles à une vue qui devrait apparaître avec la vue, tout de suite, je les mets dans la méthode ViewDidLoad. Fondamentalement, cette méthode est appelée chaque fois que la vue a été chargée en mémoire. Ainsi, par exemple, si ma vue est un formulaire avec 3 étiquettes, j'ajouterais les étiquettes ici; la vue n'existera jamais sans ces formes.
2) ViewWillAppear : J'utilise ViewWillAppear généralement juste pour mettre à jour les données sur le formulaire. Donc, pour l'exemple ci-dessus, je l'utiliserais pour charger réellement les données de mon domaine dans le formulaire. La création d'UIViews est assez coûteuse, et vous devriez éviter autant que possible de le faire avec la méthode ViewWillAppear, car lorsque cela est appelé, cela signifie que l'iPhone est déjà prêt à montrer l'UIView à l'utilisateur, et tout ce que vous faites ici aura un impact sur les performances de manière très visible (comme les animations retardées, etc.).
3) ViewDidAppear : Enfin, j'utilise ViewDidAppear pour démarrer de nouveaux threads sur des choses qui prendraient beaucoup de temps à exécuter, comme par exemple faire un appel de service Web pour obtenir des données supplémentaires pour le formulaire ci-dessus. existe déjà et est affiché à l'utilisateur, vous pouvez montrer un joli message «En attente» à l'utilisateur pendant que vous obtenez les données.
viewWillAppear
? Vous voulez dire télécharger via le réseau? Mais vous suggérez également de télécharger des éléments viewDidAppear
?
ViewDidAppear
vous risquez facilement de confondre l'utilisateur avec l'interface utilisateur :)
viewDidLoad === >>> Mettez votre code d'initialisation ici. Ne placez pas de données dynamiques susceptibles de changer au cours du cycle de vie de la vue. Donc, si vous extrayez des données à partir de données de base, vous ne voulez pas le faire ici si cela pourrait changer pendant la durée de vie de la vue. Par exemple: disons que vous avez un contrôleur d'onglets. Vous passez de tab1 à tab2 et changez quelque chose sur le modèle dans tab2. Si vous revenez à tab1 et que le code de votre modèle a été créé dans viewDidLoad, cela ne sera pas mis à jour (en supposant que vous n'utilisez pas KVO ou NSFetchedResultsController, etc.).
viewWillAppear === >>> Ceci est appelé chaque fois que la vue est sur le point d'apparaître, que la vue soit déjà en mémoire ou non. Placez votre code dynamique ici, comme la logique du modèle.
viewDidAppear === >>> Placez ici les opérations coûteuses que vous ne voulez faire que si vous êtes sûr que la vue est à l'écran, comme les appels réseau.
Remarque: si votre application est en arrière-plan et revient au premier plan, vous devez gérer cela à l'aide de NSNotificationCenter. J'ai écrit le code pour cela dans les commentaires ci-dessous. Vous pourriez penser que viewWillAppear / viewDidAppear se déclenchera. Mettez-y un point de rupture et testez-le. Il ne tire pas. Donc, si quelque chose a changé pour votre application alors qu'elle était en arrière-plan, vous devrez le mettre à jour à l'aide de notifications.
La viewWillAppear
méthode est appelée avant de charger la vue réelle.
La viewDidAppear
méthode est appelée lorsque la vue est déjà chargée et que vous souhaitez afficher quelque chose.
Quelques observations:
La viewDidLoad
méthode est appelée lors de la première instanciation de la vue. IBOutlet
les références sont connectées au moment où cela a été appelé, mais pas avant. L' frame
estime ne peut être établie au moment où cela a été appelé, cependant. C'est un excellent endroit pour ajouter / configurer des sous-vues et leurs contraintes associées. Mais si vous effectuez une configuration manuelle des frame
valeurs sur la base des dimensions de la vue principale, la configuration de ces cadres doit être différée jusqu'à viewWillAppear
ou viewDidLayoutSubviews
.
La viewWillAppear
méthode est appelée lorsque la présentation de la vue dans la hiérarchie des vues est sur le point de commencer. Notamment, cela est appelé au début de l'animation (le cas échéant) de la présentation de la vue. Son compagnon, viewWillDisappear
est évidemment appelé lorsque la transition loin de cette vue commence.
La viewDidAppear
méthode est appelée lorsque la présentation de la vue est terminée, notamment lorsque toute animation associée est terminée. Son compagnon, viewDidDisappear
est évidemment appelé lorsque la transition hors de cette vue est effectuée.
Deux mises en garde importantes:
viewDidLoad
est appelée une et une seule fois, lorsque la vue est instanciée pour la première fois. D'autre part, viewWillAppear
et viewDidAppear
sera appelé non seulement lorsque la vue est présentée pour la première fois, mais à chaque fois que la même vue en question est re-présentée. Par exemple, lorsque vous présentez une vue pour la première fois, ces trois méthodes seront appelées. Si la vue en question présente par la suite une autre vue qui est ensuite rejetée, le viewWillAppear
et viewDidAppear
sera généralement rappelé lorsque la vue en question est ajoutée et animée à nouveau dans la hiérarchie de vues, mais viewDidLoad
ne le sera pas. viewDidLoad
n'est appelée que lorsque cette instance particulière est créée pour la première fois.
Donc, si vous voulez faire quelque chose à chaque fois qu'une vue réapparaît (par exemple, vous la fermez ou y revenez), faites-le dans viewWillAppear
ou viewDidAppear
. Si vous souhaitez que cela se produise uniquement lorsque la vue est instanciée pour la première fois, faites-le dans viewDidLoad
.
L'appel de viewWillAppear
ne garantit pas que la transition vers cette vue sera jamais achevée. Notamment, si vous utilisez une transition interactive pilotée par une entrée utilisateur en temps réel, mais que cette transition interactive peut être annulée. C'est-à-dire, juste parce que viewWillAppear
c'est appelé, cela ne signifie pas que viewDidAppear
sera appelé. C'est généralement le cas, mais si le geste interactif est annulé, ce ne sera pas le cas (car la transition n'est jamais terminée).
Lors de la WWDC 2013, dans le contexte des transitions interactives, un présentateur a plaisanté en disant qu'ils devraient renommer viewWillAppear
" viewMightAppear
, ou viewWillProbablyAppear
, ou iReallyWishThisViewWouldAppear
".
Un exemple de geste interactif intégré est lorsque vous utilisez un UINavigationController
et que vous «faites glisser votre doigt depuis le bord gauche» pour lancer un pop de la vue. Le viewWillAppear
sera appelé pour la vue dans laquelle vous faites apparaître, mais si vous annulez ce "balayage depuis le bord gauche" pour revenir à la vue à partir de laquelle vous avez commencé ce geste pop, le pop est annulé et le viewDidAppear
pour la vue que vous avez commencé à pop back to ne sera jamais appelé.
L'effet net de ceci est que vous devez faire attention à ne pas écrire de code qui suppose que chaque appel à viewWillAppear
sera éventuellement suivi d'un appel à viewDidAppear
. Si la transition est annulée, ce ne sera pas le cas.
1) ViewWillAppear : La vue chargée réellement dans la mémoire, appelée une fois dans le contrôleur de vue et avait son cadre, mais n'apparaissait toujours pas à l'utilisateur
2) ViewDidAppear : Le contrôleur ajouté à la hiérarchie de la vue, vous pouvez donc présenter au contrôleur suivant, également, la vue a mis en page les sous-vues
Le premier se produit avant l'apparition de la vue et le second se produit après.
Pour résumer:
-viewWillAppear -> mettre à jour les données (recharger les données à partir d'une vue de table)
-viewDidAppear -> opérations coûteuses (appel API avec une belle progression!)
Cas d'utilisation , c'est- à- dire quand dois-je utiliser lequel?
viewDidLoad
- lorsque des étiquettes, des boutons (i, e tous les contrôles / sous-vues) sont connectés au fichier d'interface de la vue et si vous souhaitez les charger en même temps que la vue de ViewController, et si vous voulez charger ceci en mémoire une fois et être fait avec
viewWillAppear
- par exemple, vous voulez changer la couleur d'arrière-plan de la vue à chaque fois que viewController apparaît à l'écran. Ou de manière plus réaliste si vous voulez une couleur d'arrière-plan DarkMode la nuit du jour et une couleur claire de la vue d'arrière-plan pendant la journée, optez pour ce code dansviewWillAppear
Un autre bon cas d'utilisation ici https://stackoverflow.com/a/39395865/5438240
Notez également que, si vous utilisez une pile de navigation ( UINavigationController
), le viewController qui est sur le point d'être ouvert a viewWillDisappear()
appelé, et le ViewController qui sera ensuite au-dessus de la pile aura viewWillAppear()
appelé