UIViewController viewDidLoad vs viewWillAppear: Quelle est la bonne division du travail?

164

J'ai toujours été un peu incertain sur le type de tâches qui devraient être assignées à viewDidLoadvs viewWillAppear.: dans une UIViewControllersous - classe.

Par exemple, je fais une application dans laquelle une UIViewControllersous - classe frappe un serveur, récupère des données, les alimente dans une vue, puis affiche cette vue. Quels sont les avantages et les inconvénients de faire cela en viewDidLoadvs. viewWillAppear?

dugla
la source

Réponses:

251

viewDidLoad est des choses que vous devez faire une fois. viewWillAppear est appelé à chaque fois que la vue apparaît. Vous devriez faire des choses que vous n'avez à faire qu'une seule fois dans viewDidLoad - comme définir vos textes UILabel. Cependant, vous voudrez peut-être modifier une partie spécifique de la vue à chaque fois que l'utilisateur peut la voir, par exemple, l'application iPod fait défiler les paroles vers le haut à chaque fois que vous accédez à la vue "Lecture en cours".

Cependant, lorsque vous chargez des éléments depuis un serveur, vous devez également penser à la latence. Si vous regroupez toutes vos communications réseau dans viewDidLoad ou viewWillAppear, elles seront exécutées avant que l'utilisateur ne puisse voir la vue, ce qui peut entraîner un court gel de votre application. Il peut être judicieux de montrer d'abord à l'utilisateur une vue non peuplée avec un indicateur d'activité quelconque. Lorsque vous avez terminé votre mise en réseau, ce qui peut prendre une seconde ou deux (ou peut même échouer - qui sait?), Vous pouvez remplir la vue avec vos données. De bons exemples sur la façon dont cela pourrait être fait peuvent être vus dans divers clients Twitter. Par exemple, lorsque vous affichez la page de détails de l'auteur dans Twitterrific, la vue indique uniquement "Chargement ..." jusqu'à ce que les requêtes réseau soient terminées.

LéonBruxelles
la source
Donc, concernant viewWillAppear peut être appelé à plusieurs reprises. Cette méthode se déclencherait-elle si, par exemple, la vue viewcontrollers devenait visible après avoir été masquée (je veux dire occlus ici, pas la méthode masquée sur UIView). Dans quel scénario viewWillAppear serait-il appelé sans être précédé d'un appel à viewDidLoad?
dugla
7
viewDidLoad UNIQUEMENT est appelé lorsque la vue est construite - par exemple après un appel initFromNibNamed du contrôleur de vue lors de l'accès à la vue. viewWillAppear est appelé chaque fois que votre contrôleur de vue n'était pas dans la vue mais entre dans la vue - ainsi, lorsque votre contrôleur de vue est poussé, viewWillAppear est appelé. Si vous poussez une autre sous-vue à partir de là et que l'utilisateur revient, viewWillAppear est à nouveau appelé.
Kendall Helmstetter Gelner
Merci Kendall. Yah, quelques NSLogs stratégiquement placés m'ont fait trier. viewWillAppear / viewWillDissappear feu sur viewcontroller push / pops.
dugla
3
Notez que viewDidLoad sera AUSSI appelé si la vue est masquée puis déchargée pour des raisons liées à la mémoire, puis réapparaît. Ce sur quoi vous pouvez compter: viewDidLoad sera appelé AU MOINS UNE FOIS lors de la création de la vue et POSSIBLEMENT plus de fois lorsque la vue réapparaîtra après avoir été masquée. viewWillAppear sera TOUJOURS appelé lorsque la vue est sur le point d'apparaître à l'écran.
DanM
2
Quelqu'un peut-il s'il vous plaît commenter plus en détail ces deux questions connexes: (1) Parfois, pas toujours, les valeurs de cadre des contrôles (c'est-à-dire l'origine et la taille) sont nulles dans viewDidLoad, et parfois non - Pourquoi? (2) Dans le modèle d'Apple pour le detailView (iPad) d'un splitViewController, il existe une méthode configureView - que devrait-il y avoir par rapport à viewDidLoad et ViewWillAppear?
Jeff le
12

Initialement utilisé uniquement ViewDidLoad avec tableView. Lors des tests avec perte de Wifi, en mettant l'appareil en mode avion, on s'est rendu compte que la table ne s'actualisait pas avec le retour du Wifi. En fait, il ne semble y avoir aucun moyen d'actualiser tableView sur l'appareil, même en appuyant sur le bouton d'accueil avec le mode d'arrière-plan défini sur OUI dans -Info.plist.

Ma solution:

-(void) viewWillAppear: (BOOL) animated { [self.tableView reloadData];}
Jaminyah
la source
10

Il est important de noter que l'utilisation de viewDidLoad pour le positionnement est un peu risquée et doit être évitée car les limites ne sont pas définies. cela peut entraîner des résultats inattendus (j'ai eu une variété de problèmes ...)

Cet article décrit assez bien les différentes méthodes et ce qui se passe dans chacune d'elles.

actuellement pour une initialisation et un positionnement ponctuels, je pense utiliser viewDidAppear avec un drapeau, si quelqu'un a une autre recommandation, veuillez me le faire savoir.

keisar
la source
d'accord avec ceci: "... devrait être évité car les limites ne sont pas fixées ..."
danisupr4
4

Cela dépend, avez-vous besoin que les données soient chargées à chaque fois que vous ouvrez la vue? ou une seule fois ?

entrez la description de l'image ici

  • Rouge: ils n'ont pas besoin de changer à chaque fois. Une fois chargés, ils restent tels qu'ils étaient.
  • Violet: ils doivent changer au fil du temps ou après chaque chargement. Vous ne voulez pas voir les 3 mêmes utilisateurs suggérés à suivre, il doit être rechargé à chaque fois que vous revenez à l'écran. Leurs photos peuvent être mises à jour ... vous ne voulez pas voir une photo d'il y a 5 ans ...

viewDidLoad:Quel que soit le traitement que vous avez, il doit être effectué une fois.
viewWilLAppear:Quel que soit le traitement qui doit changer chaque fois que la page est chargée.

Les étiquettes, les icônes, les titres des boutons ou la plupart des donnéesInputedByDeveloper ne changent généralement pas. Les noms, photos, liens, état des boutons, listes (tableaux d'entrée pour votre tableViews ou collectionView) ou la plupart des donnéesInputedByUser changent généralement .

Mon chéri
la source
Le violet serait appelé dans la vueDidAppear pas la vueWillAppear
Alex Kornhauser
@AlexKornhauser, comment ça s'appellerait? Je dis que viewWillAppearvous pouvez interroger et vérifier les derniers tweets. viewDidAppearil est trop tard pour ça
Honey