2009-05-07 9 views
1

Wie erstelle ich einen Ladebildschirm, der jederzeit wiederverwendet werden kann. Ich kenne die Default.png, aber ich brauche die Flexibilität, einen Ladebildschirm zu jedem Zeitpunkt während des Anwendungslebenszyklus anzuschließen.Wie erstelle ich einen wiederverwendbaren Ladebildschirm?

Das ist, was ich bisher habe.

//inside a method that gets called by a UIButton 

LoadingViewController* loadController = [[LoadingViewController alloc] initWithNibName:@"Loading" bundle:nil vertical:NO]; 
[self.view addSubview: loadController.view]; 

//some method call that takes a few seconds to execute 
[self doSomething]; 

//This loads some other view, my final view 
[self.view addSubview: someOtherView] 

aber es scheint, dass die Ladeansicht nie angezeigt wird. Stattdessen bleibt die vorherige Ansicht dort, bis "someOtherView" hinzugefügt wird. Ich habe Trace-Logs geschrieben und der Code scheint ausgeführt zu werden, ich habe sogar [self doSomething] durch einen Schlaf ersetzt (2), aber die Zwischenladeansicht wird nie angezeigt.

Wenn ich [self.view entfernen addSubview: someOtherView]; dann nach ein paar Sekunden ... (nachdem doSomething fertig ausgeführt wird) wird die Ladeansicht angezeigt, da keine Ansicht darüber geschoben wird, dies ist jedoch offensichtlich nicht die Funktionalität, die ich möchte.

Kann dieses Verhalten erklären? Gibt es etwas über den Rendering-Zyklus, das ich falsch verstehe, weil es nicht scheint, dass die Ansicht (zumindest auf dem Bildschirm) sofort aktualisiert wird, obwohl ich eine [self.view addSubview: loadController.view];

Müsste ich einen separaten Thread erstellen?

Antwort

4

Im Allgemeinen für Änderungen in Wenn die Benutzeroberfläche für den Benutzer sichtbar gemacht werden soll, muss die Steuerung zum Haupt-runLoop zurückkehren. Sie kehren erst zum runLoop zurück, nachdem Sie die Ladeansicht heruntergefahren und durch die andere Ansicht ersetzt haben. Eine Strategie dafür ist, den Code zu verschieben, der das Laden auf einen anderen Thread ausführt. NSOperation und NSOperationQueue können dafür verwendet werden.

Ein noch einfacherer Ansatz ist die Verwendung von performSelectorInBackground: withObject, um die Verarbeitung durchzuführen. Sobald die Verarbeitung abgeschlossen ist, kann die Benutzeroberfläche erneut aktualisiert werden, um die Daten anzuzeigen. Es ist wichtig zu beachten, dass die UI-Updates für den Hauptthread ausgeführt werden müssen. Verwenden Sie performSelectorOnMainThread: withObject: waitUntilDone: um dies vom Lade-Thread zu erreichen.

Diese wie viele Komplikation klingt, aber es ist wirklich so einfach, wie Ihre einzige Methode in drei getrennten Verfahren zu brechen wie folgt:

  • Anzeige des Lade Ansicht und den Hintergrundprozess starten - das ist die Taste Aktionsmethode.
  • Laden Sie den Hintergrund - aufgerufen von der Schaltfläche Aktion mit performSelectorInBackground: withObject.
  • Entfernen Sie die Ladeansicht und aktualisieren Sie die Anzeige mit den Daten - aufgerufen aus dem Hintergrundthread mit performSelectorOnMainThread: withObject: waitUntilDone.
1

Ich habe eine Unterklasse von UIView erstellt, wo ich initialisiert habe, wie meine Ladeansicht funktionieren und aussehen sollte. (Meine Ansicht erschien und schob sich von unten mit einer netten Animation ein).

Ich fügte dann Code hinzu, der behandelte, ob die loading-view in einer Unterklasse von UIViewController sichtbar sein sollte oder nicht.

ich dann alle meine Viewcontrollers lassen eine Unterklasse von meiner neuen viewcontrollerclass sein, die es möglich gemacht, für mich zu tun:

[self showloadingMessage:@"loading..."]; 

in meinem Viewcontrollers ...