setNeedsDisplay n'est pas toujours appel drawRect
J'ai un affichage personnalisé dans un tableau personnalisé de la cellule. Chaque fois qu'une propriété spécifique sur la vue personnalisée est changé, j'appel [self setNeedsDisplay]
qui retrace la vue dans - (void)drawRect:(CGRect)rect
. Cette propriété est définie dans la vue table du délégué tableView:cellForRowAtIndexPath:
. Mais lors de l'affichage de la table est plus grande que l'écran et les cellules doivent être réutilisés, drawRect
n'est pas appelée à chaque fois que setNeedsDisplay
est. Surtout quand j'ai faites glisser vers la table rapidement . Ralentir le défilement fonctionne très bien. Cela conduit à l'information dans le premier et le dernier cellules étant souvent incorrecte.
Dans le journal, je peux voir que, normalement, pour chaque appel de setNeedsDisplay
il y a un appel à drawRect
, mais quand j'ai faites défiler l'affichage de la table rapidement il y a plus d'appels à setNeedsDisplay
que drawRect
. Sûrement il doit y avoir un un-à-un ratio d'ici.
- Je utiliser le même affichage personnalisé dans un normal UIView, et il redessine parfaitement et à chaque fois que j'appelle setNeedsDisplay
. Le problème semble isolé de vues de table et la réutilisation des cellules.
Personne ne sait ce qui se passe ici?
Est-il un autre moyen de forcer l'affichage personnalisé pour redessiner lui-même?
OriginalL'auteur kareman | 2009-05-17
Vous devez vous connecter pour publier un commentaire.
Je pense que j'ai du mal avec cette question depuis près d'une semaine avant j'ai trouvé le problème. Ici, il est, et je ne plaisante pas:
Le pointeur de la personnalisation de l'affichage a été défini dans le .m fichier au lieu de l' .h à rendre une variable de classe au lieu d'une variable d'instance.
Et oui, je suis très, très embarrassé.
OriginalL'auteur kareman
setNeedsDisplay
aurontdrawRect:
si la vue est visible, sinon il invalide le point de vue de la couche etdrawRect:
sera appelée lorsqu'il devient visible.Lorsque vous faites défiler une vue de la table, la vue de la table demande des cellules dans l'espoir de les ajouter à la vue. Si le défilement assez rapide, certaines cellules vont prendre trop de temps pour préparer et par le temps qu'ils sont prêts à l'endroit où ils doivent être positionnés en est hors de l'écran. Dans ces cas, l'affichage de la table des rejets au lieu de les ajouter à défilement de la vue (et donc de
drawRect:
ne sera pas appelé)Semble plausible pour les grandes tables, mais ma table a seulement 10 lignes, 8 sont visibles en même temps. Ne serait-ce pas ne s'applique que si une cellule a voyagé à partir de ci-dessous le tableau ci-dessus avant qu'il pourrait être redessinée?
Oui, qui ne s'appliquerait que pour les grandes tables. Dans votre tableau de 8 lignes visibles devraient recevoir drawRect:... si ce n'est que c'est probablement un bug quelque part. Vous pouvez poster votre code (ou une version simplifiée qui a toujours le bug)?
Il s'avère que, même lors de chaque appel à setNeedsDisplay résultats dans un appel à drawRect, le contenu de la vue personnalisée est encore souvent mal. Et lorsque vous faites défiler normalement la vue personnalisée qui est sur le point d'apparaître souvent être retracée dans une cellule qui est déjà visible à l'autre bout de la table! Ce qui n'a absolument aucun sens. Cette vidéo (nottoobadsoftware.com/Repetitions/drawrect_bug.mov), il explique mieux. Attention à la deuxième cellule à partir du bas. Chaque ligne a une étiquette sur le dessus et une vue personnalisée en dessous (le dernier texte dans la vue personnalisée, c'est juste pour des fins de débogage).
Parfois, d'autres cellules sont retracées comme ça. BTW: quand le problème a changé autant qu'il a ici, dois-je juste reformuler la question ou de créer une nouvelle question? Je veux dire que le titre n'est pas encore précis. Comme vous pouvez le voir de mon score, je suis nouveau ici.
OriginalL'auteur rpetrich
Vous devriez appeler
[_table_ reloadData]
le rafraîchissement de la table. Pas[_table_cell_ setNeedsDsiplay]
reloadData appels setNeedsDisplay pour vous au bon moment. Vous semblez être la lutte contre le cadre. Laissez le cadre de décider lesquels de mettre à jour et mettre en œuvre tableView:cellForRowAtIndexPath:
reloadData provoque toutes les cellules de la table pour être détruit, la source de données pour être réinterrogée, et les cellules visibles à être recréé. C'est beaucoup plus que ce qui est nécessaire pour simplement actualiser une seule cellule.
Merci pour votre réponse, j'ai eu des problèmes dans UITableView. J'ai une cellule personnalisé de la vue et de la coutume UIView dans cette cellule personnalisé. Personnalisé UIView n'a pas l'appel drawRect fonction lorsque l'utilisateur arrivé 2ème fois. Votre reloadData résolu mon problème.
OriginalL'auteur amattn
Il semble que il ya deux circonstances dans lesquelles l'affichage est actualisé: si la valeur interne de changements (et que vous appelez
[self setNeedsDisplay]
pour forcer une mise à jour), et aussi si la tableview demande une cellule de dessiner (ou réutilisés). Vous n'êtes pas explicitement redessiner que l'affichage personnalisé dans cette situation.Selon les docs:
Si tableview est le recyclage des cellules, il va remettre une cellule avec les anciennes valeurs toujours en place. C'est à vous de assurez-vous que le contenu est mis à jour. Selon la façon dont vous avez configuré votre tableau personnalisé cellulaire, vous pourriez avoir à faire plus pour s'assurer que la vue est à jour, mais la chose la plus simple serait dans la cellule du tableau gestionnaire de forcer un appel à
[myCustomView setNeedsDisplay]
.Essayez de défilement de la cellule en dehors de la vue & en arrière pour voir si le changement prend effet. Je viens de me rappeler que j'ai déposé un rapport de bogue sur ce problème précis (Bogue #6022064: UITableViews et la mise à jour de l'accessoire de vues) de l'année dernière. Ils m'ont répondu qu'ils ne pouvaient pas reproduire le bug. Dans mon cas, un navcontroller a été appelé, il serait de modifier la couleur de la accessoryView et setNeedsDisplay appelait, mais quand vous êtes allé en arrière, il ne serait pas actualiser. Le défilement des cellules hors de la table & retour serait montrer la bonne couleur. Si elle agit de la même & vous pouvez l'isoler, peut-être vous pouvez soumettre et dupe le bug.
OriginalL'auteur Ramin