Optimisation de performances sur un affichage de UIViews

muqaddarmuqaddar Administrateur
février 2015 modifié dans API UIKit #1

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 !


 


Réponses

  • CéroceCéroce Membre, Modérateur

    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.


  • muqaddarmuqaddar Administrateur


    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.

  • Joanna CarterJoanna Carter Membre, Modérateur
    Tu ne pourrais pas dessiner les bouteilles dans le drawRect de la vue ?
  • muqaddarmuqaddar Administrateur


    Tu ne pourrais pas dessiner les bouteilles dans le drawRect de la vue ?




     


    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.

  • MalaMala Membre, Modérateur


    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.




    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.


  • muqaddarmuqaddar Administrateur
    février 2015 modifié #8


    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?




     


    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.


  • muqaddarmuqaddar Administrateur
    février 2015 modifié #9


    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.




     


    Non, c'est pas adapté, surtout vu la forme des casiers que je peux avoir (diamond, triangle...)


  • LeChatNoirLeChatNoir Membre, Modérateur

    /* hors sujet */


    Mala, je vois que tu n'as tjs pas changé le title de ton site Web.... Fais le !


    /* fin du HS */


  • Joanna CarterJoanna Carter Membre, Modérateur


    Non, c'est pas adapté, surtout vu la forme des casiers que je peux avoir (diamond, triangle...)




     


    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

  • muqaddarmuqaddar Administrateur


    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.

  • Joanna CarterJoanna Carter Membre, Modérateur


    ç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.




     


    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.

  • FKDEVFKDEV Membre
    février 2015 modifié #14

    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.


  • muqaddarmuqaddar Administrateur


    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.




     


    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. 


  • muqaddarmuqaddar Administrateur


    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é. ;)

  • muqaddarmuqaddar Administrateur


    C'est quoi des systèmes de multi-répétition ?


     




     


    Des répétitions possibles au sein du même casier, ce qui évite de multiplier les casiers.


     




     


    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.




     


     ç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 !

  • Bien, mais tu as combien de classes qui dérivent de casier ?


    Cela me fait penser l'optimisation des overlays dans mapkit dont le principe d'affichage a été modifé dans ios 7:



    Note: In iOS 7.0 and later, MKOverlayRenderer replaces MKOverlayView. Renderers provide the same functionality as views, but they are more lightweight and efficient.

    [\quote]
Connectez-vous ou Inscrivez-vous pour répondre.