Was ist der Unterschied zwischen -[UIViewController viewWillAppear:]
und -[UIViewController viewDidAppear:]
?
Was ist der Unterschied zwischen -[UIViewController viewWillAppear:]
und -[UIViewController viewDidAppear:]
?
Antworten:
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.
viewWillAppear
? Du meinst das Herunterladen über das Netzwerk? Aber Sie schlagen auch vor, Sachen herunterzuladen viewDidAppear
?
ViewDidAppear
Sie Benutzer leicht über die Benutzeroberfläche verwirren :)
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.
Die viewWillAppear
Methode wird vor dem Laden der eigentlichen Ansicht aufgerufen.
Die viewDidAppear
Methode wird aufgerufen, wenn die Ansicht bereits geladen ist und Sie etwas anzeigen möchten.
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)
Einige Beobachtungen:
Die viewDidLoad
Methode wird aufgerufen, wenn die Ansicht zum ersten Mal instanziiert wird. IBOutlet
Referenzen werden zu dem Zeitpunkt angeschlossen, an dem dies aufgerufen wurde, jedoch nicht zuvor. Die frame
Ansicht 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 frame
Werten auf der Grundlage der Abmessungen der Hauptansicht vornehmen, sollte die Konfiguration dieser Frames bis viewWillAppear
oder verschoben werden viewDidLayoutSubviews
.
Die viewWillAppear
Methode 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 viewWillDisappear
wird offensichtlich genannt, wenn der Übergang von dieser Ansicht weg beginnt.
Die viewDidAppear
Methode wird aufgerufen, wenn die Präsentation der Ansicht abgeschlossen ist, insbesondere wenn alle zugehörigen Animationen abgeschlossen sind. Sein Begleiter viewDidDisappear
wird offensichtlich genannt, wenn der Übergang von dieser Ansicht erfolgt ist.
Zwei wichtige Vorbehalte:
viewDidLoad
wird einmal und nur einmal aufgerufen, wenn die Ansicht zum ersten Mal instanziiert wird. Auf der anderen Seite viewWillAppear
und viewDidAppear
wird 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 viewWillAppear
und viewDidAppear
im Allgemeinen erneut aufgerufen, wenn die betreffende Ansicht hinzugefügt und wieder in die Ansichtshierarchie animiert wird, dies viewDidLoad
wird jedoch nicht der Fall sein . viewDidLoad
wird 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 viewWillAppear
oder viewDidAppear
. Wenn dies nur beim ersten Instanziieren der Ansicht geschehen soll, tun Sie dies in viewDidLoad
.
Der Aufruf von viewWillAppear
garantiert 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 viewWillAppear
es gerufen wird, heißt das nicht, dass viewDidAppear
es 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 viewWillAppear
in " viewMightAppear
, oder viewWillProbablyAppear
oder iReallyWishThisViewWouldAppear
" umbenennen sollten .
Ein Beispiel für eine integrierte interaktive Geste ist die Verwendung von a UINavigationController
und "Wischen Sie vom linken Rand", um einen Popup der Ansicht auszulösen. Das viewWillAppear
wird 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 viewDidAppear
fü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 viewWillAppear
schließlich ein Aufruf von folgt viewDidAppear
. Wenn der Übergang abgebrochen wird, ist dies nicht der Fall.
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
Ersteres geschieht, bevor die Ansicht angezeigt wird, und letzteres danach.
Um zusammenzufassen:
-viewWillAppear -> Daten aktualisieren (Daten aus einer Tabellenansicht neu laden)
-viewDidAppear -> teure Operationen (API-Aufruf mit einem schönen Fortschritt hud!)
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