24

Ich versuche, aus Apples sketchy Dokumentation herauszufinden, welche Methode der beste Ort ist, um meine Ansichten-Steuerelemente zu initialisieren und der Ansicht des Controllers hinzuzufügen.programmiere ich SubViews in ViewDidAppear, ViewDidLoad, ViewWillAppear, dem Konstruktor?

Mit winforms ist es ziemlich einfach, da sie immer innerhalb InitializeDesigner initialisiert werden, im Konstruktor aufgerufen. Ich versuche, die Zuverlässigkeit dieses Musters wenn möglich zu vergleichen.

Ich arbeite mit UIViewControllers und UITableViewControllers innerhalb einer UINavigationController die meiste Zeit - wenn dies alles bewirkt.

Hier ist ein Beispiel:

public MyController() 
{ 
    // Here? 
    AddViews(); 
} 

public override ViewDidLoad() 
{ 
    base.ViewDidLoad(); 

    // Or is should it be here? 
    AddViews(); 
} 

public override ViewWillAppear(bool) 
{ 
    base.ViewWillAppear(animated); 

    // Here? 
    AddViews(); 
} 

public override ViewDidAppear(bool animated) 
{ 
    base.ViewDidLoad(animated); 

    // Or maybe here? 
    AddViews(); 
} 

void AddViews() 
{ 
    UILabel label = new UILabel(); 
    label.Text = "Test"; 
    label.Frame = new RectangleF(100,100,100,26); 
    View.AddSubView(label); 

    UIWebView webview = new UIWebView(); 
    webview .Frame = new RectangleF(100,100,100,26); 
    View.AddSubView(webview); 
} 

ich gemischte Ergebnisse mit einigen UIControls bekommen, wenn ich sie zu der Ansicht in verschiedenen Orten hinzufügen. Visual Lag manchmal, manchmal ist das Webview irgendwo versteckt.

Gibt es eine allgemeine Regel zum Hinzufügen?

+2

Siehe auch: http://stackoverflow.com/questions/573958/iphone-sdk-what-is-the-difference-between-loadview-and-viewdidload –

Antwort

70

In der Regel ist dies, was ich tue:

  • ViewDidLoad - Jedes Mal, wenn ich Kontrollen zu einer Ansicht hinzufügen, die mit der Ansicht, sofort erscheinen zusammen sollen, ich habe es in den ViewDidLoad Methode. Grundsätzlich wird diese Methode immer dann aufgerufen, wenn die Ansicht in den Speicher geladen wurde. Wenn meine Ansicht beispielsweise ein Formular mit drei Labels ist, würde ich die Labels hier hinzufügen. ohne diese Formen wird die Ansicht niemals existieren.

  • ViewWillAppear: Ich benutze ViewWillAppear normalerweise nur um die Daten auf dem Formular zu aktualisieren. Für das obige Beispiel würde ich das verwenden, um die Daten meiner Domäne tatsächlich in das Formular zu laden. Die Erstellung von UIViews ist ziemlich teuer, und Sie sollten so viel wie möglich mit der ViewWillAppear-Methode vermeiden, denn wenn diese aufgerufen wird, bedeutet das, dass das iPhone bereits bereit ist, dem Benutzer die UIView zu zeigen, und alles, was Sie hier tun wirkt sich sehr gut auf die Leistung aus (z. B. verzögerte Animationen usw.).

  • ViewDidAppear: Schließlich verwende ich die ViewDidAppear neue Themen, um die Dinge zu beginnen, das eine lange Zeit, um einen Webservice Aufruf tat zusätzliche Daten für das Formular auszuführen, wie zum Beispiel nehmen würde oben zu bekommen.Die gute Sache ist, dass, weil die Ansicht bereits existiert und dem Benutzer angezeigt wird, Sie eine nette "Wartende" Nachricht an den Benutzer zeigen können, während Sie die Daten erhalten.

Es gibt jedoch andere Tricks, die Sie verwenden können. Nehmen wir an, Sie möchten, dass ein UILabel in das Formular "fliegt", nachdem das Formular geladen wurde. In diesem Fall würde ich das Label dem Formular in der ViewDidLoad hinzufügen, aber mit einem Frame außerhalb des Ansichtsbereichs, und dann würde ich in der ViewDidAppear die Animation machen, um es wieder in die Ansicht zu fliegen.

Ich hoffe, es hilft.

+0

Danke das ist viel geklärt. Ich konnte nichts mit dem LoadView-Beispiel aus dieser Frage hinzufügen: http://stackoverflow.com/questions/573958/iphone-sdk-what-is-the-difference-between-loadview-and-viewdidload-do Hast du jemals diese Methode benutzt? –

+1

LoadView ist also im Prinzip eine Methode aus dem UIViewController (Verwenden Sie den Rosettenstein, wenn Sie versuchen, diese Dinge herauszufinden - http://tirania.org/tmp/rosetta.html). Das Framework ruft diese Methode automatisch im Controller auf, um sie anzuweisen, Ansichten zu erstellen, und die Standardimplementierung von UIViewController ruft dann ViewDidLoad auf. Obwohl Sie diese Methode überschreiben können (und dafür sorgen, dass Sie die Basismethode aufrufen, wenn Sie das tun), bevorzuge ich es, einfach nur viewWillLoad (vor loadView aufgerufen) und viewDidLoad (kurz danach aufgerufen) zu verwenden. –

+0

@eduardo, docs raten, super auf loadView nicht aufzurufen –

8

Hmm, Apples Dokumentation scheint ziemlich klar zu sein, IMHO.

Wenn Sie eine eigene Root-Ansicht (die Stammansicht dieses speziellen Controllers Ansichtshierarchie) erstellen programmatisch, sollten Sie es schaffen, in -loadView ohne super Aufruf und stellen Sie die view Eigenschaft, wenn Sie fertig. Wenn Ihre Ansicht von einer Feder geladen wird, sollten Sie nicht -loadView berühren.

Sie fügen der View-Controller-Ansicht benutzerdefinierte Subviews hinzu oder ändern sie in -viewDidLoad. Die empfohlene Vorgehensweise besteht darin, UILabel und UIWebView in -viewDidLoad zu erstellen und sie in -viewDidUnload freizugeben, indem Sie ihre Referenzen auf nil setzen, wenn Sie sie in ivar aufbewahren müssen.

Hinweis: -viewDidUnload ist in iOS 6 veraltet und wird nur nicht mehr aufgerufen, weil UIViewController seine Ansicht nicht mehr unter Speicherdruck löscht.

+0

Danke Ich habe diese Methode verpasst. Ich habe immer noch das Gefühl, dass die Methoden, die ich aufgelistet habe, sehr begrenzte Informationen darüber geben, wann sie verwendet werden sollten. Sogar in loadView wird alles gesagt: * 'Wenn Sie eine zusätzliche Initialisierung Ihrer Ansichten durchführen möchten, tun Sie dies in der viewDidLoad-Methode' * - wann würden Sie diese Methode jemals brauchen? –

+0

loadView ist die Methode, die entweder die Ansichtshierarchie aus der NIB lädt oder nur eine leere UIView erstellt, wenn keine NIB geladen werden soll. Möglicherweise möchten Sie stattdessen eine benutzerdefinierte Ansicht, in der Sie loadView überschreiben. UITableViewController zum Beispiel überschreibt diese Methode, um eine UITableView zu erstellen. Ich finde oft, dass ich dasselbe mit meinen eigenen UIView-Unterklassen mache. – Costique

+0

viewDidUnload ist veraltet –

2

viewDidLoad bezieht sich auf "MEMORY" und viewWillAppear/viewDidAppear auf "APPEARANCE". Die Ansicht eines Ansichtscontrollers (der eine Stammansicht der Ansichten Ihres Ansichtscontrollers darstellt) kann mehrmals erscheinen/verschwinden, selbst wenn die Ansicht des Controllers bereits im Speicher ist.

(Wenn ich mich auf root-view beziehe, meine ich auch seine Subviews, weil der Root-View auf seine Kinder (Subviews) verweist, aber aus Sicht des View-Controllers kennt er normalerweise nur den Root-View Subviews können normalerweise über die Ausgänge des View-Controllers erfolgen.)

Die Root-Ansicht selbst kann aus dem Speicher gelöscht werden, wenn eine Speicherwarnung vorliegt. Der View-Controller bestimmt, wann der beste Zeitpunkt ist, um sie aus dem Speicher zu entfernen.

Normalerweise würden Sie Subviews in viewDidLoad hinzufügen, weil das Hinzufügen von Subviews bedeutet, dass sie dem Speicher hinzugefügt werden. ABER nicht, wenn Sie alle Ihre Ansichten programmgesteuert erstellen (nicht aus einer NIB-Datei). Wenn dies der Fall ist, sollten Sie die loadView-Methode überschreiben und eine Stammansicht erstellen und dort Teilansichten hinzufügen. In diesem Fall können Sie viewDidLoad auslassen, um Teilansichten hinzuzufügen.