Was ist der Unterschied zwischen -viewWillAppear: und -viewDidAppear:?

131

Was ist der Unterschied zwischen -[UIViewController viewWillAppear:]und -[UIViewController viewDidAppear:]?

PJR
quelle
1
danke BoltClock, aber bitte geben Sie mir ein Beispiel von beiden, wenn möglich ..
PJR
3
@ BoltClock wäre es schön wenn das wahr wäre. Ich vermute, die 15 Leute, die positiv bewertet haben, haben den Methodennamen gelesen, ihn aber nie gemessen ... Kam von Google hierher, weil das NICHT der Unterschied zwischen ihnen ist
Adam
1
Insbesondere: parentView.viewDidAppear wird eine lange Zeit genannt, bevor Apple tatsächlich parentView anzeigt ... Apple malt zuerst (atomar) alle Unteransichten ... und wenn Sie viele oder komplexe Unteransichten haben, kann "viewDidAppear" als Zehner bezeichnet werden oder Hunderte von Millisekunden zu früh :(.
Adam

Antworten:

291

Im Allgemeinen mache ich Folgendes:

1) ViewDidLoad - Immer wenn ich einer Ansicht Steuerelemente hinzufüge, die zusammen mit der Ansicht angezeigt werden sollen, füge ich sie sofort in die ViewDidLoad-Methode ein. Grundsätzlich wird diese Methode immer dann aufgerufen, wenn die Ansicht in den Speicher geladen wurde. Wenn meine Ansicht beispielsweise ein Formular mit 3 Beschriftungen ist, würde ich die Beschriftungen hier hinzufügen. Die Ansicht wird ohne diese Formen niemals existieren.

2) ViewWillAppear : Ich verwende ViewWillAppear normalerweise nur, um die Daten im Formular zu aktualisieren. Für das obige Beispiel würde ich dies verwenden, um die Daten aus meiner Domain tatsächlich in das Formular zu laden. Das Erstellen von UIViews ist ziemlich teuer, und Sie sollten dies bei der ViewWillAppear-Methode so weit wie möglich vermeiden, da dies bedeutet, dass das iPhone bereits bereit ist, die UIView dem Benutzer anzuzeigen, und alles, was Sie hier tun wirkt sich auf sehr sichtbare Weise auf die Leistung aus (z. B. verzögerte Animationen usw.).

3) ViewDidAppear : Schließlich verwende ich ViewDidAppear, um neue Threads für Dinge zu starten, deren Ausführung lange dauern würde, wie zum Beispiel einen Webservice-Aufruf, um zusätzliche Daten für das obige Formular abzurufen. Das Gute ist, dass die Ansicht existiert bereits und wird dem Benutzer angezeigt. Sie können dem Benutzer eine nette "Warten" -Nachricht anzeigen, während Sie die Daten erhalten.

Chetan Bhalara
quelle
4
Entschuldigung, aber was meinst du mit "Laden der Daten von meiner Domain in das Formular" in viewWillAppear? Du meinst das Herunterladen über das Netzwerk? Aber Sie schlagen auch vor, Sachen herunterzuladen viewDidAppear?
Philip007
1
@ Philip007 Ich denke, Stack bezieht sich auf diese Art von Domain: en.wikipedia.org/wiki/Domain-specific_modeling . Die Daten werden von Ihren Modellen oder ähnlichem geladen.
Dentarg
2
Diese Antwort sollte in den Dokumenten stehen. Es war sehr hilfreich, um den Unterschied zwischen den drei Methoden zu klären. Danke dir!
GangstaGraham
1
+1 Ich hatte ein wenig Verwirrung, als ich den Unterschied zwischen diesen drei verstand, aber Sie haben es gerade mehr als perfekt geklärt. @ChetanBhalara
Chisx
@ChetanBhalara, aber wenn Sie lange arbeiten, werden ViewDidAppearSie Benutzer leicht über die Benutzeroberfläche verwirren :)
hqt
46

viewDidLoad === >>> Geben Sie hier Ihren Initialisierungscode ein. Fügen Sie keine dynamischen Daten ein, die sich während des Ansichtslebenszyklus ändern könnten. Wenn Sie also Daten aus Kerndaten abrufen, möchten Sie dies hier nicht tun, wenn sich dies während der Lebensdauer der Ansicht ändern könnte. Beispiel: Angenommen, Sie haben einen Registerkarten-Controller. Sie wechseln von Tab1 zu Tab2 und ändern etwas am Modell in Tab2. Wenn Sie zu tab1 zurückkehren und Ihr Modellcode in viewDidLoad erstellt wurde, wird dieser nicht aktualisiert (vorausgesetzt, Sie verwenden nicht KVO oder NSFetchedResultsController usw.).

viewWillAppear === >>> Dies wird jedes Mal aufgerufen, wenn die Ansicht angezeigt wird, unabhängig davon, ob sich die Ansicht bereits im Speicher befindet oder nicht. Fügen Sie hier Ihren dynamischen Code ein, z. B. die Modelllogik.

viewDidAppear === >>> Fügen Sie hier teure Vorgänge ein, die Sie nur ausführen möchten, wenn Sie sicher sind, dass die Ansicht auf dem Bildschirm angezeigt wird, z. B. Netzwerkanrufe.

Hinweis: Wenn Ihre App im Hintergrund ist und in den Vordergrund zurückkehrt, müssen Sie dies mit NSNotificationCenter erledigen. Ich habe den Code dafür in den Kommentaren unten geschrieben. Sie könnten denken, viewWillAppear / viewDidAppear wird ausgelöst. Setzen Sie dort einen Haltepunkt und testen Sie ihn. Es feuert nicht. Wenn sich also im Hintergrund etwas für Ihre App geändert hat, müssen Sie dies mithilfe von Benachrichtigungen aktualisieren.

smileBot
quelle
1
Wird ViewWill oder ViewDid jedes Mal ausgeführt, wenn Sie die Minimierung der Anwendung aufheben?
Jeef
2
@Jeef Dies ist eine ausgezeichnete Frage. Beides wird nur ausgeführt, wenn die App im Hintergrund vom System oder vom Benutzer beendet wird. Um benachrichtigt zu werden, wenn die App nicht minimiert ist, müssen Sie NSNotificationCenter und addObserver für den Namen UIApplicationWillEnterForegroundNotification verwenden. Der Selektor sollte applicationWillEnterForeground sein: Er hat einen NSNotification-Parameter. Fügen Sie Ihren Code in diese Methode ein, um Daten usw. neu zu laden. Sie können eine Methode zum erneuten Laden erstellen, die Sie aus dieser Methode aufrufen, und viewDidAppear anzeigen, wenn diese identisch sein müssen.
smileBot
2
@Jeef so etwas wie: - (void) viewDidLoad {[[NSNotificationCenter defaultCenter] addObserver: Selbstselektor: @selector (applicationWillEnterForeground :) Name: UIApplicationWillEnterForegroundNotification Objekt: nil]; } - (void) applicationWillEnterForeground: (NSNotification *) notif {// hier mit was auch immer antworten}
smileBot
12

Die viewWillAppearMethode wird vor dem Laden der eigentlichen Ansicht aufgerufen.

Die viewDidAppearMethode wird aufgerufen, wenn die Ansicht bereits geladen ist und Sie etwas anzeigen möchten.

Puneet Kathuria
quelle
9

viewWillAppear:
Wird aufgerufen, bevor die Ansicht zur Ansichtshierarchie der Fenster hinzugefügt wird.
■ Wird vor [vc.view layoutSubviews] aufgerufen (falls erforderlich)
viewDidAppear :
Wird aufgerufen, nachdem die Ansicht zur Ansichtshierarchie hinzugefügt wurde.
■ Wird nach [vc.view layoutSubviews] aufgerufen. (Falls benötigt)

andyqee
quelle
7

Einige Beobachtungen:

  • Die viewDidLoadMethode wird aufgerufen, wenn die Ansicht zum ersten Mal instanziiert wird. IBOutletReferenzen werden zu dem Zeitpunkt angeschlossen, an dem dies aufgerufen wurde, jedoch nicht zuvor. Die frameAnsicht kann jedoch zu dem Zeitpunkt, zu dem dies aufgerufen wurde, möglicherweise nicht festgelegt werden. Dies ist ein großartiger Ort, um Unteransichten und die damit verbundenen Einschränkungen hinzuzufügen / zu konfigurieren. Wenn Sie jedoch eine manuelle Konfiguration von frameWerten auf der Grundlage der Abmessungen der Hauptansicht vornehmen, sollte die Konfiguration dieser Frames bis viewWillAppearoder verschoben werden viewDidLayoutSubviews.

  • Die viewWillAppearMethode wird aufgerufen, wenn die Darstellung der Ansicht in der Ansichtshierarchie beginnen soll. Dies wird insbesondere zu Beginn der Animation (falls vorhanden) der Präsentation der Ansicht aufgerufen. Sein Begleiter viewWillDisappearwird offensichtlich genannt, wenn der Übergang von dieser Ansicht weg beginnt.

  • Die viewDidAppearMethode wird aufgerufen, wenn die Präsentation der Ansicht abgeschlossen ist, insbesondere wenn alle zugehörigen Animationen abgeschlossen sind. Sein Begleiter viewDidDisappearwird offensichtlich genannt, wenn der Übergang von dieser Ansicht erfolgt ist.

Zwei wichtige Vorbehalte:

  • viewDidLoadwird einmal und nur einmal aufgerufen, wenn die Ansicht zum ersten Mal instanziiert wird. Auf der anderen Seite viewWillAppearund viewDidAppearwird nicht nur aufgerufen, wenn die Ansicht zum ersten Mal präsentiert wird, sondern jedes Mal, wenn dieselbe betreffende Ansicht erneut präsentiert wird. Wenn Sie beispielsweise zum ersten Mal eine Ansicht präsentieren, werden alle drei Methoden aufgerufen. Wenn die betreffende Ansicht anschließend eine andere Ansicht darstellt, die anschließend verworfen wird, wird das viewWillAppearund viewDidAppearim Allgemeinen erneut aufgerufen, wenn die betreffende Ansicht hinzugefügt und wieder in die Ansichtshierarchie animiert wird, dies viewDidLoadwird jedoch nicht der Fall sein . viewDidLoadwird nur aufgerufen, wenn diese bestimmte Instanz zum ersten Mal erstellt wird.

    Wenn Sie also jedes Mal etwas tun möchten, wenn eine Ansicht erneut angezeigt wird (z. B. Sie schließen sie oder kehren zu ihr zurück), tun Sie dies in viewWillAppearoder viewDidAppear. Wenn dies nur beim ersten Instanziieren der Ansicht geschehen soll, tun Sie dies in viewDidLoad.

  • Der Aufruf von viewWillAppeargarantiert nicht, dass der Übergang zu dieser Ansicht jemals abgeschlossen wird. Insbesondere, wenn Sie einen interaktiven Übergang verwenden, der durch Benutzereingaben in Echtzeit gesteuert wird, dieser interaktive Übergang jedoch abgebrochen werden kann. Das heißt, nur weil viewWillAppeares gerufen wird, heißt das nicht, dass viewDidAppeares gerufen wird. Im Allgemeinen ist dies der Fall, aber wenn die interaktive Geste abgebrochen wird, wird dies nicht der Fall sein (da der Übergang nie abgeschlossen wurde).

    Auf der WWDC 2013 scherzte ein Moderator im Rahmen interaktiver Übergänge, dass sie viewWillAppearin " viewMightAppear, oder viewWillProbablyAppearoder iReallyWishThisViewWouldAppear" umbenennen sollten .

    Ein Beispiel für eine integrierte interaktive Geste ist die Verwendung von a UINavigationControllerund "Wischen Sie vom linken Rand", um einen Popup der Ansicht auszulösen. Das viewWillAppearwird für die Ansicht aufgerufen, in die Sie eintauchen. Wenn Sie jedoch das "Wischen vom linken Rand" abbrechen, um zu der Ansicht zurückzukehren, von der aus Sie diese Pop-Geste gestartet haben, wird das Pop abgebrochen und das viewDidAppearfür die Ansicht, mit der Sie begonnen haben pop back to wird niemals aufgerufen.

    Der Nettoeffekt davon ist, dass Sie darauf achten sollten, dass Sie keinen Code schreiben, der davon ausgeht, dass auf jeden Aufruf von viewWillAppearschließlich ein Aufruf von folgt viewDidAppear. Wenn der Übergang abgebrochen wird, ist dies nicht der Fall.

rauben
quelle
5

viewwillappear wird vor dem Laden der Ansicht aufgerufen, damit Sie bestimmte Aufgaben ausführen können, bevor Sie diese Ansicht laden, und viewdidappear wird nach dem Laden der Ansicht aufgerufen, damit die Post-Aufgabe in dieser Methode ausgeführt wird

dks1725
quelle
4

Unterschied zwischen "will" und "did" ... Wie der Name schon sagt, wird viewWillAppear aufgerufen, bevor die Ansicht angezeigt wird, und viewDidAppear wird aufgerufen, wenn view angezeigt wurde.

Mahesh
quelle
Schauen Sie sich die akzeptierte Antwort an, die mehr als 70 Upvotes enthält. :)
PJR
4

1) ViewWillAppear : Die Ansicht wurde tatsächlich in den Speicher geladen, einmal im Ansichts-Controller aufgerufen und hatte ihren Rahmen, wurde dem Benutzer jedoch immer noch nicht angezeigt

2) ViewDidAppear : Der Controller wurde zur Ansichtshierarchie hinzugefügt, sodass Sie ihn dem nächsten Controller präsentieren können. Außerdem hat die Ansicht die Unteransichten gestaltet

Abuzeid Ibrahim
quelle
3

Ersteres geschieht, bevor die Ansicht angezeigt wird, und letzteres danach.

Marc Abramowitz
quelle
3

Um zusammenzufassen:

-viewWillAppear -> Daten aktualisieren (Daten aus einer Tabellenansicht neu laden)

-viewDidAppear -> teure Operationen (API-Aufruf mit einem schönen Fortschritt hud!)

Nahuel Roldan
quelle
1

Wie der Name schon sagt, wird das viewWillAppearaufgerufen, bevor die Ansicht angezeigt wird, und viewDidAppearwird aufgerufen, wenn die Ansicht angezeigt wurde.

visakh7
quelle
0

Usecase , dh wann soll ich welche verwenden?

viewDidLoad - Wenn Beschriftungen, Schaltflächen (d. h. Steuerelemente / Unteransichten) mit der Schnittstellendatei der Ansicht verbunden sind und wenn Sie alle diese gleichzeitig mit der Ansicht des ViewControllers laden möchten und wenn Sie diese einmal in den Speicher laden möchten und sein möchten damit fertig

viewWillAppear- Angenommen, Sie möchten die Hintergrundfarbe der Ansicht jedes Mal ändern, wenn der viewController auf dem Bildschirm angezeigt wird. Oder realistischer, wenn Sie die DarkMode-Hintergrundfarbe zur Tageszeit und die helle Farbe der Hintergrundansicht zur Tageszeit wünschen, wählen Sie diesen Code inviewWillAppear

Ein weiterer guter Anwendungsfall hier https://stackoverflow.com/a/39395865/5438240

Beachten Sie außerdem, dass bei Verwendung eines Navigationsstapels ( UINavigationController) der viewController, der viewWillDisappear()kurz vor dem Popup steht, aufgerufen wird und der ViewController, der sich als Nächstes über dem Stapel befindet, viewWillAppear()aufgerufen hat

Naishta
quelle