[Résolu] UIControl ou UITapGestureRecognizer ?

busterTheobusterTheo Membre
mars 2015 modifié dans API UIKit #1

Bonjour,


je fais ce qui suit, sur des layers, dans une view.


Déjà , je pense que c'est mieux de manipuler des layers plutôt que des subViews. Ai-je raison ?


 


Sans quoi voilà  le topo.


 


Je dois manipuler les extrémités d'une ligne à  partir de ses deux poignées droite et gauche (deux petits ronds pleins), tout ça conçu avec drawRect, contexte, etc...


 


J'hésite quant à  la meilleure méthode à  utiliser.


 


Est-il préférable d'utiliser UIControl, ou plutôt UITapGestureRecognizer, pour détecter les positions des poignées et redessiner ma ligne en fonction  d'elles ?


 


Personnellement, je trouve que c'est plus simple avec UITapGestureRecognizer, mais est-ce conforme ?


 


Voilà , j'espère que ma question est explicite..


 


Merci d'avance


 


busterTheo


Réponses

  • Bon, toujours pas de réponse.


    Alors je me répond à  moi-même, pour ceux qui comme moi, sont un peu neuhneuh.


     


    Malheureusement, je pense, après avoir mieux compris la situation, suite à  de nombreux tutos du web. Il semblerait que si l'on veut cliquer et déplacer des objets, UIControl s'impose, alors que UITapGestureRecognizer soit d'avantage pour la détection du nombre de taps, sans grosse gestion ultérieure des positions d'objets. Ouaaahhhh, j'ai l'air super clair !!!


     


    Je vais donc travailler tout ça, et je mettrai une petite vidéo en ligne, si j'y parviens, bien sûr.


  • CéroceCéroce Membre, Modérateur

    Bonjour,
    je fais ce qui suit, sur des layers, dans une view.
    Déjà , je pense que c'est mieux de manipuler des layers plutôt que des subViews. Ai-je raison ?

    Les UIViews utilisent des CALayers. Les CALayers sont plus lègères que les vues, mais ne gèrent pas les événements. Donc, ça dépend. Dans ton cas, l'avantage d'utiliser des vues peut être que tu saurais précisément quelle est la zone (vue) concernée.
     

    Est-il préférable d'utiliser UIControl, ou plutôt UITapGestureRecognizer, pour détecter les positions des poignées et redessiner ma ligne en fonction  d'elles ?

    Disons que tu te méprends sur le rôle de UIControl. Un contrôle sert à  fixer une valeur.
    Là , ton choix est plutôt entre interpréter les évenements de toucher sur une UIView ou utiliser les Gesture Recognizers. Je te déconseille la première approche, qui est difficile et peut mener à  des comportements non-standards.
  • busterTheobusterTheo Membre
    février 2015 modifié #4

    Merci, Céroce, pour ta réponse.


     


    Je ne sais plus à  quel saint me vouer. Puisque ma ligne doit bouger en fonction des x/y des ronds...


     


    En même temps, je préfère de loin les Gesture Recognizer aux UIControls, c'est plus facile. Je suis d'accord avec toi.


     


    Voilà  un exemple dont je dois m'inspirer


    http://www.magnitude-6.net/ge/Ceroce.mov


     


    Qu'en penses-tu ?


    ça risque être chaud avec les Gesture Recognizers, non ?


     


     


     


    Merci d'avance


  • AliGatorAliGator Membre, Modérateur
    - CALayers = uniquement la partie dessin sans la partie gestion d'événements
    - UIView = rajoute la gestion des événements (toute UIView a une "@property CALayer* layer" pour gérer son rendu graphique sous le capot)
    - UIControl = + dédié aux boutons, sliders, etc

    Je te conseille donc les UIGestureRecognizer comme tu étais parti pour faire, c'est à  mon avis la solution la plus adaptée et la moins prise de tête.
  • Merci AliGator pour ces précieuses précisions.


     


    Donc, si je comprend bien :


     


    Voir le lien http://www.magnitude-6.net/ge/Ceroce.mov


     


    Je met mon UIImageView


     


    J'y met 3 subViews (une ligne bezier et deux ronds)


     


    Je dessine ma ligne dans un CALayer dans la subView ligne


    Je dessine mon rond1 dans un CALayer dans la subView rond1

    Je dessine mon rond2 dans un CALayer dans la subView rond2

     

    Puis je fait du UIGestureRecognizer sur chacune des subViews ronds, pour modifier le CALayer ligne de la subView ligne.

     

    Ouaaahh. Si c'st bon, j'ai plus qu'à  bruler mes neurones.

     

    Merci d'avance

  • AliGatorAliGator Membre, Modérateur
    Alors oui c'est presque ça que j'avais en tête à  part que tu n'es pas obligé de passer explicitement par les layers pour dessiner tes lignes et ton rond.


    Tu peux le faire avec des CAShapeLayer auxquelles tu fournis le BezierPath que tu veux et les paramètres de rendu type couleur, épaisseur de trait etc..., mais tu peux aussi demander de dessiner directement ton trait et tes ronds. Et pour ça pas besoin de passer par le CALayer explicitement, il suffit d'implémenter la méthode drawRect: de UIView qui est faite pour ça (et dans ce cas tu fais totalement abstraction du fait que ça utilise des CALayer sous le capot t'as même pas besoin de le savoir tu te contentes de dessiner dans ta vue avec les méthodes de CoreGraphics " voir le Quartz2D Programming Guide dans la doc Apple)
  • Bonsoir,


     


    Il y a quelques temps, j'avais des recherches sur les CALayers et les CAShapeLayers et certains développeurs avaient noté des dégradations de performance à  partir d'un certain nombre d'objets (plusieurs centaines).


    Je ne sais pas si cela est toujours le cas mais du coup, j'avais renoncé à  les utiliser.


    Du coup je fais tout sur une seule UIView manuellement.


  • AliGatorAliGator Membre, Modérateur
    Je pense que la cumulation d'un nombre conséquent de CALayers et CAShapeLayers peut peut-être avoir effectivement un impact sur les perfs, bien qu'effectivement il faudrait réactualiser ce genre d'études (il y a bien une époque où on nous disait de dessiner nos UITableViewCells manuellement avec drawRect si on voulait de la performance... alors que ce n'est plus vrai maintenant !)... mais c'est vraiment dans le cas où on s'oriente dans une application où il risque d'y en avoir *vraiment* beaucoup (sans doute le cas pour iPocket Draw je suppose).

    Dans le cas de busterTheo, je ne pense pas que ce soit encore le cas, et de toute façon je pense qu'il n'en n'est pas au stade où l'optimisation des performances de cette envergure est nécessaire (c'est pas comme si utiliser 20 CALayers dans ton appli allait la faire laguer ;)) donc à  mon avis c'est le moindre de ses soucis, ce n'est pas un critère de décision à  ce stade et pour un projet débutant de petite envergure.


    Par contre un avantage d'utiliser CALayer / CAShapeLayer par rapport à  tout dessiner à  la main avec drawRect(), c'est que CALayer est tout à  fait adapté pour les animations. J'ai déjà  fait plusieurs composants custom (genre des graphes "Barres"/Histogrammes ou autres) où les formes devaient être animées avec des CABasicAnimation & co (pas juste bougées à  la main, mais qu'on voit l'animation de la forme d'une position à  une autre, avec la barre qui part de 0 et grandit jusqu'à  sa valeur finale lors de l'apparition du graphe, etc). Alors que si tu dessines sur ton UIView comme un canvas avec drawRect(), c'est quand même pas la panacée si tu veux ensuite faire de l'animation ;-)
  • busterTheobusterTheo Membre
    février 2015 modifié #10

    Bonjour,


    tout d'abord, merci à  tous pour vos précisions.


     


    J'ai donc fait tout ça avec uniquement des views dans une view et des tap et pan gestureRecognizer.


     


    ça donne ça.


    http://www.magnitude-6.net/ge/poignees.mov


     


    Et j'ai mis le projet ici.


    http://www.magnitude-6.net/ge/Layer10.zip


     


    Si ça peut servir à  quelqu'un, ce serait super.


     


    Au cas où on m'offrirait quelques critiques, au niveau conformité, performances, ou autres. J'apprécierais grandement.


     


    Merci d'avance.


     


    Le projet est prévu en position Paysage sur iPad.


  • Bonjour,


    aucune critique ?


     


    Je suis donc sur la bonne voie...


  • CéroceCéroce Membre, Modérateur

    Si ça marche, ça marche. Problème suivant !


  • Ah, merci Céroce


    Je me posais juste des questions sur la conformité et les performances...


Connectez-vous ou Inscrivez-vous pour répondre.