2009-05-07 6 views
1

Comment créer un écran de chargement réutilisable à un moment donné? Je suis au courant de Default.png mais j'ai besoin de la flexibilité pour brancher un écran de chargement à tout moment pendant le cycle de vie de l'application.Comment créer un écran de chargement réutilisable?

C'est ce que j'ai jusqu'ici.

//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] 

mais il semble que la vue de chargement ne soit jamais affichée. Au lieu de cela, la vue précédente reste là jusqu'à ce que "someOtherView" soit ajouté. Je mets des logs de trace et le code semble être exécuté, j'ai même remplacé [self doSomething] par sleep (2), mais la vue de chargement intermédiaire n'est jamais affichée.

Si je supprime [self.view addSubview: someOtherView]; puis après quelques secondes ... (après que doSomething ait terminé l'exécution), la vue de chargement est affichée car il n'y a aucune vue qui est poussée dessus, mais ce n'est évidemment pas la fonctionnalité que je veux.

Peut expliquer ce problème? Y a-t-il quelque chose à propos du cycle de rendu que je ne comprends pas parce qu'il ne semble pas que la vue (sur l'écran au moins) soit instantanément mise à jour, même si j'appelle un [self.view addSubview: loadController.view];

Aurais-je besoin de créer un thread séparé?

Répondre

4

En général, les changements de l'interface utilisateur doit être rendue visible à l'utilisateur, le contrôle doit retourner à la ligne d'exécution principale. Vous ne retournez au runLoop qu'après avoir pris la vue de chargement et l'avoir remplacée par l'autre vue. Une stratégie pour gérer cela consiste à déplacer le code qui effectue le chargement sur un autre thread. NSOperation et NSOperationQueue peuvent être utilisés pour cela.

Une approche encore plus simple consiste à utiliser performSelectorInBackground: withObject pour effectuer le traitement. Une fois le traitement terminé, l'interface utilisateur peut être mise à jour à nouveau pour afficher les données. Il est important de se rappeler que les mises à jour de l'interface utilisateur doivent être effectuées sur le thread principal. Utilisez performSelectorOnMainThread: withObject: waitUntilDone: pour accomplir ceci à partir du thread de chargement.

Cela ressemble à beaucoup de complications, mais il est vraiment aussi simple que la rupture de votre seule méthode en trois méthodes distinctes:

  • Affichez la vue de chargement et démarrer le processus d'arrière-plan - c'est le bouton méthode d'action.
  • Effectue le chargement en arrière-plan - appelé depuis la fonction d'action du bouton avec performSelectorInBackground: withObject.
  • Supprimez la vue de chargement et mettez à jour l'affichage avec les données - appelées à partir du thread d'arrière-plan avec performSelectorOnMainThread: withObject: waitUntilDone.
1

J'ai créé une sous-classe de UIView où j'ai initialisé comment ma vue de chargement devrait fonctionner et ressembler. (Ma vue est apparue et a glissé du fond avec une belle animation).

J'ai ensuite ajouté du code qui traitait si la vue de chargement devait être visible ou non dans une sous-classe de UIViewController.

Je laisse alors tous mes viewcontrollers être une sous-classe de mon nouveau viewcontrollerclass qui a permis pour moi de faire:

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

dans tous mes viewcontrollers ...

Questions connexes