J'ai un contrôle segmenté utilisé comme bascule. Quand on bascule, je change un tas de contenus dans une vue de table qui prend un temps minuscule mais perceptible (insérer/supprimer des sections dans la vue tableau, animer le changement, etc.). Je veux que le contrôle segmenté réponde immédiatement à la sélection. Donc, dans mon action code de gestion pour l'événement UIControlEventValueChanged du contrôle segmentée, je fais ce qui suit:Maintien d'un UISegmentedControl (parmi d'autres) sensible
- (IBAction)groupingChanged:(id)sender {
UISegmentedControl *seg = sender;
[tableModel toggleOn:[seg selectedSegmentIndex] == ToggleOnIndex];
[self performSelectorOnMainThread:@selector(updateGrouping)
withObject:nil
waitUntilDone:NO];
}
Où updateGrouping
est:
- (void)updateGrouping {
MXAssertMainThread();
[tableView beginUpdates];
... several table updates
[tableView endUpdates];
}
Réglage waitUntilDone:NO
permet la méthode groupingChanged
avant l'interruption updateGrouping
est appelée, mais cela ne semble pas suffisant pour repeindre la vue. Le contrôle segmenté colle jusqu'à ce que la table soit mise à jour, puis elle bascule.
J'ai donc essayé de modifier groupingChanged:
pour créer un fil pour la mise à jour comme ceci:
- (void)delayed {
[self performSelectorOnMainThread:@selector(updateGrouping)
withObject:nil
waitUntilDone:NO];
}
- (IBAction)groupingChanged:(id)sender {
UISegmentedControl *seg = sender;
[tableModel toggleOn:[seg selectedSegmentIndex] == ToggleOnIndex];
[self performSelectorInBackground:@selector(delayed) withObject:nil];
}
Et cela fonctionne. Le contrôle segmenté bascule instantanément et la table suit rapidement. Mais je ne suis pas du tout confiant du résultat. Est-ce simplement un effet secondaire de donner un répit au thread principal pendant le démarrage du nouveau thread? Est-ce juste comment j'ai besoin de mettre en file d'attente des mises à jour à l'interface utilisateur? C'est clairement hacky. J'espère que quelqu'un a un meilleur modèle qu'ils suivent pour cette situation.
Cela élimine le thread provisoire, donc c'est une amélioration, mais je refuse de croire qu'il n'y a pas de motif commun non-hacky. –
performSelector: withObject: afterDelay est également valide comme le souligne Kendall. Ce problème est que la boucle d'exécution doit être terminée pour permettre à l'interface utilisateur de se mettre à jour. Ce n'est pas vraiment un hack, mais juste en reconnaissant ce fait. De toute façon, je ne connais pas de mise à jour de l'interface utilisateur sans permettre au thread principal de suivre son cours. –
Bien sûr, je réalise la cause. Je suppose que j'espérais un modèle commun pour cela. Crédit accordé (tardif). –