2010-10-07 3 views
2

J'essaie d'afficher un UIProgressView en haut d'une vue de table après certaines interactions utilisateur. Dans ma vue de table, si l'utilisateur appuie sur une cellule particulière, je glisse un UIView qui contient une barre d'outils avec des éléments de barre et une vue sélecteur (il se comporte très bien comme une feuille d'action). Lorsque je fais cela, j'ajoute la vue hors écran à la vue actuelle, puis j'anime la diapositive. Lorsque l'utilisateur fait une sélection et appuie sur "terminé", la vue se rétracte. À ce stade, la vue d'avancement est censée apparaître et se mettre à jour lorsque certaines choses se produisent en arrière-plan. Le problème que j'ai est qu'après la "feuille d'alerte" UIView est sorti de la vue actuelle, rien ne se passe dans l'interface utilisateur pendant un bon moment. Quand je montre la vue coulissante, je fais ceci:Affichage pas de mise à jour, mais tout sur le thread principal

[[[UIApplication sharedApploication] keyWindow] addSubview:slidingView]; 
CGRect newFrame = CGRectMake(...); 
[UIView animateWithDuration:0.3 
    animations:^{ 
     slidingView.frame = newFrame; 
    }]; 

Lorsque l'utilisateur tape sur le bouton « fait » dans la vue de glissement, cette méthode d'action est invoquée:

- (void) done { 
    NSNumber *row = GetSelectedRowSomehow(); 

    [self dismiss:@selector(doneCallback:) withObject:row]; 
} 

- (void) dismiss:(SEL)cb withObject:(id)obj { 
    [UIView animateWithDuration:0.3 
     animations:^{ 
      slidingView.frame = CGRectMake(...); 
     } 
     completion:^(BOOL finished) { 
      [self.delegate performSelectorOnMainThread:cb 
              withObject:obj 
             waitUntilDone:NO]; 
      [slidingView performSelectorOnMainThread:@selector(removeFromSuperview:) 
              withObject:nil 
             waitUntilDone:NO]; 
     }]; 
} 

Le rappel appelée ici:

- (void) doneCallback { 
    self.dialogView.hidden = NO; 
    self.progressView.progress = 0; 

    for (float i = 0; i < 1.0; i += 0.1) { 
     self.progressView.progress += i; 
     sleep(0.5); 
    } 
} 

Dans mon cas, dialogView ne semble pas qu'après callback terminée. Pourquoi ne pas simplement mettre à jour l'affichage immédiatement après que sa propriété hidden ait été définie sur NO?

Répondre

2

L'affichage est mis à jour dans le thread principal une fois que votre code a fini d'exécuter, donc en bloquant le thread principal vous empêchez cela. L'une des raisons à cela est que les mises à jour sont regroupées afin qu'elles puissent être redessinées efficacement. Une solution/solution de contournement serait d'utiliser performSelector: afterDelay: 0.01 to dans doneCallback après hidden = NO, en déplaçant le code suivant dans un nouveau sélecteur qui s'exécute après le délai. Vous pouvez également exécuter le code dans "doneCallback" en arrière-plan (bien que vous ne puissiez pas directement mettre UIKit à jour à partir du thread d'arrière-plan, vous devrez donc envoyer des messages au thread principal pour toutes les mises à jour).

+0

Merci. Je pensais que c'était quelque chose comme ça, mais j'ai essayé quelques trucs pour essayer de mettre à jour l'interface utilisateur qui ne fonctionnait pas, donc j'étais un peu perdue parce que je m'attendais juste à ce que ça marche. Il est utile de savoir que les mises à jour des lots de l'interface utilisateur (j'aurais dû savoir). J'ai fini par pousser la plus grande partie vers une file d'attente de dispatch et maintenant l'interface utilisateur se met à jour comme il se doit. –

Questions connexes