Optimisation de performances sur un affichage de UIViews
Cette fois, je cherche à améliorer les performances de l'affichage de nombreuses UIViews.
Dans la capture ci-dessous, j'ai 400 vues - une pour le background, une pour la bouteille si présente - tout ceci est dans une UIScrollView.
Cela prend 5 secondes pour l'affichage !
Connectez-vous ou Inscrivez-vous pour répondre.
Réponses
Affiches-tu vraiment toutes les vues en même temps ? Je veux dire, est ce que contenu défile et seules certaines vues sont affichées à chaque instant.
Toutes les vues sont affichées en même temps.
De toute façon la capture montre 75% des vues à l'écran. Et au moins mon scroll est fluide.
3 choses:
1. ça veut dire qu'à chaque tap dans la vue, je dois prendre les coordonnées du tap et faire des calculs pour savoir dans quelle bouteille je suis en cas de déplacement (c'est pas si simple, il y a 45 types de casiers différents, avec chacun des systèmes de multi-répétitions et des espaces). Alors que là , un tap dans ma vue et je sais quelle bouteille bouge.
2. J'ai toujours lu que tout ce qui se passait dans drawRect était mauvais en terme de performances, et pas seulement quand on anime.
3. Il n'y a pas que l'affichage (addSubview) qui prend du temps, en effet quand je dessine le casier, je vérifie si une des bouteilles du casier est présente à cet emplacement, et ça prend 1/3 du temps cité ci-dessus.
Non.
Faire un affichage par subviews ça oui c'est une cata en terme de perfs. J'espère au moins que tes représentations de bouteilles c'est du bitmap et pas du vectoriel?
ScrollView?
Est-ce qu'une `UICollectionView` serait intéressant avec son système de reuse, et d'allocation/init uniquement sur demande (quand on les affiche) ? Après, t'as peut-être fait ça manuellement dans ton UIScrollView.
Oui, c'est du bitmap.
Donc tu incites à tout dessiner dans la même vue ?
C'est facile, mais le problème de déplacement des bouteilles sera autre.
Non, c'est pas adapté, surtout vu la forme des casiers que je peux avoir (diamond, triangle...)
/* hors sujet */
Mala, je vois que tu n'as tjs pas changé le title de ton site Web.... Fais le !
/* fin du HS */
On peut ranger les cellules à n'importe quelle forme. À WWDC, ils ont fait un cercle dont les cellules s'ajoutent au centre et prennent leurs places sur le radius
ça me refait refaire tout mon système de drawing et je n'ai pas envie. Et en plus, c'est trop spécifique à iOS, plutôt qu'une vue.
Par contre, j'ai lu tout et son contraire sur les performances entre addSubview:imageView et image.drawInRect, donc si vous avez des conseils valables, je suis preneur.
J'utilise le Visitor Pattern pour dessiner les objets ; du coup, je peut utiliser le même visiteur soit pour iOS, soit pour OS X.
C'est quoi des systèmes de multi-répétition ?
J'opterais pour une solution mixte.
Le casier est une UIView dans une collection view de casier. Si les casier sont toujours en grille de rectangle, ça s'y prête bien.
A l'intérieur du casier, tu utilises des approches diverses : tu dessines avec drawRect quand c'est facile, tu restes comme aujourd'hui quand c'est dur.
Donc, tu as une classe de base MUQCasier (ou un protocole) que tu pourras dériver pour chaque forme de casier, ce qui te laisse la possibilité soit d'utiliser DrawRect, soit de garder des UIView dans la classe dérivée.
Dans la classe de base MUQCasier, tu définis les méthodes communes que devra implémenter chaque type de casier. C'est la partie la plus critique : définir un jeu d'interfaces valable pour tous les types de casier.
Rien ne t'empêche de définir une classe (MUQCell) pour chaque emplacement qui ne soit pas dérivé d'UIView mais qui puisse t'aider pour dessiner et pour repérer les touches.
A priori chaque objet MUQCell aurait un pointeur vers un objet du modèle qui lui donnerait sa position. Elle aurait également la position (x,y) de son centre (s'il n'y a pas de bouteille rectangulaire, ça suffit). Et encore dans la plupart des casier je pense que la position du centre peut-être déduite assez facilement du rang (répétition?) dans le casier.
C'est vraiment un cas typique où une bonne approche objet est adaptée. C'est aussi un cas où il faut avoir une approche en arbre (cave-casier-bouteille) pour faciliter les calculs lors du dessin et de la detection de position.
Je vais regarder ça, merci.
Tu pourrais peut-être jeter un oeil sur SpriteKit et utiliser une vue de type SKView juste pour dessiner tes bouteilles, avec des SKSpriteNode.
ça c'est pour la prochaine version, car oui j'y ai pensé.
Des répétitions possibles au sein du même casier, ce qui évite de multiplier les casiers.
ça c'est déjà le cas.
J'ai même Cave => Casier => Répétition => Emplacement (avec bouteille ou non).
Je vais faire des tests avec drawRect().
Merci à vous !
Cela me fait penser l'optimisation des overlays dans mapkit dont le principe d'affichage a été modifé dans ios 7: