2009-08-07 5 views
2

J'essaye de mettre à jour une barre de progression UIProgressView que j'ai dans un UIView pendant un long processus de chargement de ressources. Disons que je charge un tas de bitmaps à partir d'un fichier NIB (comme peut-être une centaine). Après avoir chargé 10, j'émets un .progress à UIProgressView qui fait partie d'un UIView déjà affiché. Alors, je lance:UIProgressView ne se met pas à jour pendant que mon application charge ses ressources

myView.myProgressView.progress=0.2; 

Ensuite, je charge un autre 10 bitmaps et numéro:

myView.myProgressView.progress=0.4; 

etc., etc. Lors de l'exécution d'applications, la barre de progression ne fait pas avancer. Il reste simplement à sa position initiale. Au risque de sonner comme un crétin complet, dois-je charger mes ressources sur un fil séparé afin que le système d'exploitation puisse mettre à jour l'interface utilisateur, ou, est-il un moyen plus facile? Merci pour toute aide.

Répondre

1

Oui. Chargez-les sur un fil séparé. Ou tout simplement utiliser quelque chose comme performSelector:

[self performSelector:@selector(setProgressBar) withObject:nil afterDelay:0.0]; 

(et créer une fonction setProgressBar qui lit la valeur actuelle d'une variable de membre et met à jour l'interface utilisateur)

+0

Salut, Marcc, J'ai essayé votre approche performSelector en vain. La méthode setProgressBar a été appelée AFTER tout mon autre code terminé. Je n'ai même pas essayé de mettre à jour UIProgressView. J'ai simplement mis un NSLog dans setProgressBar et qui est sorti sur la console après toutes les autres méthodes de chargement de ressources. D'autres suggestions ? Peux-tu me montrer une référence pour avoir fait tout ça sur un autre fil? – kspeacock

+1

Oups. Donc, l'idée est bonne, vous devez mettre à jour les données sur un thread et ne pas bloquer le thread principal (thread UI) tout en le faisant. Je pense que vous devez réellement utiliser performSelectorOnMainThread si vous adoptez cette approche (recherchez dans le site du développeur les documents sur celui-ci). – marcc

0

Vous pouvez exécuter une étape du runloop après chaque mise à jour l'interface utilisateur:

SInt32 result; 
do { 
    result = CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0, TRUE); 
} while(result == kCFRunLoopRunHandledSource); 

Il pourrait avoir d'autres conséquences néfastes (par exemple, permettre à l'utilisateur d'interagir avec l'interface utilisateur, exécuter les délégués du contrôleur de vue tels que viewDidAppear avant doivent être exécutés, etc.) alors soyez très, v très prudent.