UIViewController viewDidLoad vs. viewWillAppear: Was ist die richtige Arbeitsteilung?

164

Ich war mir immer ein bisschen unklar, welche Art von Aufgaben viewDidLoadvs. viewWillAppearin einer UIViewControllerUnterklasse zugewiesen werden sollten .

Beispiel: Ich mache eine App, bei der eine UIViewControllerUnterklasse auf einen Server trifft, Daten abruft, sie einer Ansicht zuführt und diese Ansicht dann anzeigt. Was sind die Vor- und Nachteile davon im viewDidLoadVergleich zu viewWillAppear?

Dugla
quelle

Antworten:

251

viewDidLoad ist etwas, was Sie einmal tun müssen. viewWillAppear wird jedes Mal aufgerufen, wenn die Ansicht angezeigt wird. Sie sollten Dinge tun, die Sie in viewDidLoad nur einmal tun müssen - wie das Festlegen Ihrer UILabel-Texte. Möglicherweise möchten Sie jedoch einen bestimmten Teil der Ansicht jedes Mal ändern, wenn der Benutzer sie anzeigt. Beispielsweise scrollt die iPod-Anwendung die Texte jedes Mal nach oben, wenn Sie zur Ansicht "Aktuelle Wiedergabe" wechseln.

Wenn Sie jedoch Dinge von einem Server laden, müssen Sie auch über die Latenz nachdenken. Wenn Sie Ihre gesamte Netzwerkkommunikation in viewDidLoad oder viewWillAppear packen, werden sie ausgeführt, bevor der Benutzer die Ansicht sehen kann - was möglicherweise zu einem kurzen Einfrieren Ihrer App führt. Es kann eine gute Idee sein, dem Benutzer zuerst eine nicht ausgefüllte Ansicht mit einer Aktivitätsanzeige anzuzeigen. Wenn Sie mit Ihrem Netzwerk fertig sind, was ein oder zwei Sekunden dauern kann (oder sogar fehlschlagen kann - wer weiß?), Können Sie die Ansicht mit Ihren Daten füllen. Gute Beispiele dafür finden sich in verschiedenen Twitter-Clients. Wenn Sie beispielsweise die Autorendetailseite in Twitterrific anzeigen, wird in der Ansicht nur "Laden ..." angezeigt, bis die Netzwerkabfragen abgeschlossen sind.

LeonBrüssel
quelle
In Bezug auf viewWillAppear wird möglicherweise wiederholt aufgerufen. Würde diese Methode ausgelöst, wenn beispielsweise die Ansicht der Viewcontroller nach dem Ausblenden sichtbar würde (ich meine hier verdeckt, nicht die ausgeblendete Methode in UIView). In welchem ​​Szenario würde viewWillAppear aufgerufen, ohne dass ein Aufruf von viewDidLoad vorausgeht?
Dugla
7
viewDidLoad wird NUR aufgerufen, wenn die Ansicht erstellt wird - beispielsweise nach einem Aufruf des Ansichtscontrollers initFromNibNamed, wenn auf die Ansicht zugegriffen wird. viewWillAppear wird immer dann aufgerufen, wenn Ihr View Controller nicht angezeigt wurde, aber angezeigt wird. Wenn also Ihr View Controller gedrückt wird, wird viewWillAppear aufgerufen. Wenn Sie von dort aus eine andere Unteransicht verschieben und der Benutzer zurückkehrt, wird viewWillAppear erneut aufgerufen.
Kendall Helmstetter Gelner
Danke Kendall. Yah, ein paar strategisch platzierte NSLogs haben mich sortiert. viewWillAppear / viewWillDissappear Feuer auf Viewcontroller Push / Pops.
Dugla
3
Beachten Sie, dass viewDidLoad AUCH aufgerufen wird, wenn die Ansicht ausgeblendet und dann aus speicherbezogenen Gründen entladen wird, und dann erneut angezeigt wird. Worauf Sie zählen können: viewDidLoad wird MINDESTENS EINMAL aufgerufen, wenn die Ansicht zum ersten Mal erstellt wird, und möglicherweise mehrmals, wenn die Ansicht nach dem Ausblenden wieder angezeigt wird. viewWillAppear wird IMMER aufgerufen, wenn die Ansicht auf dem Bildschirm angezeigt wird.
DanM
2
Kann jemand bitte diese beiden verwandten Fragen weiter kommentieren: (1) Manchmal, nicht immer, sind die Frame-Werte für Steuerelemente (dh Ursprung und Größe) in viewDidLoad Null und manchmal nicht - Warum? (2) In Apples Vorlage für detailView (iPad) eines splitViewControllers gibt es eine configureView-Methode - was sollte dort in Bezug auf viewDidLoad und ViewWillAppear enthalten sein?
Jeff
12

Anfangs nur ViewDidLoad mit tableView verwendet. Beim Testen mit Wifi-Verlust wurde durch Einstellen des Geräts in den Flugzeugmodus festgestellt, dass die Tabelle bei Rückkehr von Wifi nicht aktualisiert wurde. Tatsächlich scheint es keine Möglichkeit zu geben, tableView auf dem Gerät zu aktualisieren, selbst wenn Sie auf die Home-Schaltfläche klicken und der Hintergrundmodus in -Info.plist auf YES gesetzt ist.

Meine Lösung:

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

Es ist wichtig zu beachten, dass die Verwendung von viewDidLoad zur Positionierung etwas riskant ist und vermieden werden sollte, da die Grenzen nicht festgelegt sind. Dies kann zu unerwarteten Ergebnissen führen (ich hatte verschiedene Probleme ...)

Dieser Beitrag beschreibt recht gut die verschiedenen Methoden und was in jeder von ihnen passiert.

Derzeit für eine einmalige Initialisierung und Positionierung Ich denke darüber nach, viewDidAppear mit einem Flag zu verwenden. Wenn jemand eine andere Empfehlung hat, lass es mich bitte wissen.

Keisar
quelle
stimme dem zu: "... sollte vermieden werden, da die Grenzen nicht gesetzt sind ..."
danisupr4
4

Abhängig davon: Müssen die Daten bei jedem Öffnen der Ansicht geladen werden ? oder nur einmal ?

Geben Sie hier die Bildbeschreibung ein

  • Rot : Sie müssen nicht jedes Mal geändert werden. Sobald sie geladen sind, bleiben sie so, wie sie waren.
  • Lila: Sie müssen sich im Laufe der Zeit oder nach jedem Laden ändern. Sie möchten nicht die gleichen 3 vorgeschlagenen Benutzer sehen, denen Sie folgen müssen. Sie müssen jedes Mal neu geladen werden, wenn Sie zum Bildschirm zurückkehren. Ihre Fotos werden möglicherweise aktualisiert ... Sie möchten kein Foto von vor 5 Jahren sehen ...

viewDidLoad: Welche Verarbeitung Sie auch haben, diese muss einmal durchgeführt werden.
viewWilLAppear:Unabhängig von der Verarbeitung, die sich bei jedem Laden der Seite ändern muss.

Beschriftungen, Symbole, Schaltflächentitel oder die meisten dataInputedByDeveloper ändern sich normalerweise nicht. Namen, Fotos, Links, Schaltflächenstatus, Listen (Eingabearrays für Ihre tableViews oder collectionView) oder die meisten dataInputedByUser ändern sich normalerweise .

Honig
quelle
Das Lila würde in der viewDidAppear aufgerufen werden, nicht in der viewWillAppear
Alex Kornhauser
@AlexKornhauser wie meinst du es würde heißen? Ich sage in Ihrem können viewWillAppearSie die neuesten Tweets abfragen und überprüfen. viewDidAppear
Honey