Appui long sur une UIView pour la déplacer sur l'IHM

JérémyJérémy Membre
février 2017 modifié dans API UIKit #1

Bonjour à  tous,


 


Dans le but de déplacer une UIView sur mon IHM, j'ai choisi un appui long suivi d'un glissé. Seulement, pour éviter que ma vue en chevauche une autre, je souhaiterai déplacer celle qui se trouvera en dessous au bout de 2 secondes après que la première se soit retrouvé sous la seconde. Ce que je ne sais pas vraiment faire c'est de déclencher l'action après les deux secondes sachant que si l'utilisateur déplace de nouveau la fenêtre, le compteur doit repartir à  0 et le user doit attendre deux secondes supplémentaires.


 


Voici le code :



func longPressAction(gesture: UILongPressGestureRecognizer) {
if gesture.state == .began {
...
}
else if gesture.state == .changed {
// Attende de deux secondes et si l'utilisateur n'a pas bougé la view entre temps
// on lance l'action de réorganisation de l'IHM
}
else if gesture.state == .ended {
...
}
}

Pouvez vous me mettre sur la voie ?


 


Merci pour vos réponses. ^_^


Réponses

  • Pourquoi ces deux secondes ? 


    Déjà  ça va être coton pour que l'utilisateur ne bouge pas le doigt pendant 2 secondes (tu peux mettre une sorte de dead zone mais bon...) et ça va être une punition à  utiliser ton affaire.


     


    L'idéal serait de faire en sorte que le déplacement se fasse quand les 2 centres de vues se retrouvent à  une certaine distance. C'est plus dynamique et ça évite un lag qui va en énerver plus d'un.


  • JérémyJérémy Membre
    février 2017 modifié #3
    Ouai tu as raison. Mais le truc c'est qu'il faudrait que ça déclenche le déplacement des autres views lorsque tu es proche du centre d'une view et que tu ne déplaces plus ta view courante (comme la gestion des déplacements des icônes sur iOS), tu saurais comment faire pour capter ce moment ?
  • Moi je ferai gérer ça par la superview.


    Tu fais un protocol pour le gérer avec un manager que tu renseigne à  la création de tes vues filles. (comme un delegate en gros).


    DeÌ€s que tu drag une vue tu en informe le manager et lui s'occupe des calculs et du déplacement des autres vues. Il faut pour ça que tu geÌ€re un peu plus finement ta view hierarchy donc ta superview doit aussi être custom.


  • Okay mais comment (techniquement) capter le fait que le déplacement se soit arrêté (alors que nous sommes toujours en appuis long dessus) ? Il existe un gesture recognizer qui détermine l'état d'un éventuel déplacement ?


  • Exemple, l'utilisation d'un UIPanGestureRecognizer acouplé à  l'état "Ended" dans la méthode "translation" peut faire l'affaire ?


  • Tant que tu n'as pas levé le doigt tu notifies le manager deÌ€s qu'il y a un mouvement. On peut approfondir ça un peu plus tard là  je suis au boulot.


  • Ca marche ! Car la je suis un peu dans le flou... ::)


  • dispatch_after ?
  • JérémyJérémy Membre
    février 2017 modifié #10


    dispatch_after ?




     


    Je connais pas...


     


    Mais je ne sais  si mon explication du début est très clair pour vous. ???


     


    Je veux créer (grosso modo) la même expérience utilisateur que lorsque nous déplaçons des icons sur l'écran d'accueil de l'iPhone ou iPad.


     


    1 - Un appui long


    2 - Je choisis une position


    3 - Lorsque je m'arrête, je déplace les autres éléments


    4 - Je lâche la view


  • Et si tu commençais d'abord par nous dire ce que tu voulais faire au final.


    Il y a peut être déjaÌ€ un framework qui fait tout ça. Sinon on te filera un coup de main  


  • Regarde dispatch_after !




  •  


    Je veux créer (grosso modo) la même expérience utilisateur que lorsque nous déplaçons des icons sur l'écran d'accueil de l'iPhone ou iPad.


     


    1 - Un appui long


    2 - Je choisis une position


    3 - Lorsque je m'arrête, je déplace les autres éléments


    4 - Je lâche la view




     


    Tu veux dire un appuui lonnnggggg ? J'ai toujours eu horreur du délai d'attente interminable défini par Apple pour activer le déplacement des icônes du bureau.

  • JérémyJérémy Membre
    février 2017 modifié #14

    Il y a peut être déjà  un framework qui fait tout ça. Sinon on te filera un coup de main



     

    Je ne souhaite pas utiliser de framework. Pourquoi ? Je n'ai pas appris à  faire des requête SQL en utilisant un requêteur automatique.  ::)

     



    Et si tu commençais d'abord par nous dire ce que tu voulais faire au final.



     

    Okay je recommence :

     



    Je veux créer (grosso modo) la même expérience utilisateur que lorsque nous déplaçons des icons sur l'écran d'accueil de l'iPhone ou iPad.

     

    1 - Un appui long

    2 - Je choisis une position

    3 - Lorsque je m'arrête, je déplace les autres éléments

    4 - Je lâche la view



     

    J'ai fait un schéma pour illustrer ma demande.


     




    Tu veux dire un appuui lonnnggggg ?




     


    Ouiiiiiiiiiiiiiiiiii ! Même si mon problème ne vient pas de l'appuis long mais de déplacer les autres élément mais lorque j'ai déplacé ma vieux, que je me sois arrêter à  un endroit et (à  ce moment là ) les autres View se déplacent.


     




    Regarde dispatch_after !




     


    Ca constiste en quoi ?  :)


  • Joanna CarterJoanna Carter Membre, Modérateur
    Je te conseillerais de chercher comment utiliser UICollectionView. Si je m'en souviens correctement, J'ai regardé un video de WWDC mais, je ne peut pas, a ce moment, me souvenir de quelle année. Il y a aussi un demo qui montre comment faire ce que tu veut avec.


  • Je te conseillerais de chercher comment utiliser UICollectionView.




     


    Tu peux avoir le comportement que je souhaite avec un UICollectionView ?


     


    Mais ke truc c'est que j'aurais aimer le faire à  la main pour apprendre.  ::)



  • Tu peux avoir le comportement que je souhaite avec un UICollectionView ?




     


    Oui Jérémy ! Regarde ce lien, tu vas trouver ton bonheur.


     


    http://nshint.io/blog/2015/07/16/uicollectionviews-now-have-easy-reordering/


     


    Maintenant si tu souhaites créer ce composant à  la main, les autres membres du forum seront plus calés que moi pour répondre à  tes questions.  ;)

  • Merci !  ;D


  • Joanna CarterJoanna Carter Membre, Modérateur
    février 2017 modifié #19


    Tu peux avoir le comportement que je souhaite avec un UICollectionView ?


    De ce que je comprends, oui


    Mais ke truc c'est que j'aurais aimer le faire à  la main pour apprendre. ::)


    Tu veux réinventer encore une roue ? Pourquoi? Apple l'a déjà  fait pour toi ; en-profites


    WWDC 2012 sessions 205 et 219
  • Joanna CarterJoanna Carter Membre, Modérateur

    Maintenant si tu souhaites créer ce composant à  la main, les autres membres du forum seront plus calés que moi pour répondre à  tes questions.  ;)




    Pas moi. Tu as déjà  trouvé ton bonheur. Vas-y :)


  • Tu veux réinventer encore une roue ? Pourquoi? Apple l'a déjà  fait pour toi ; en-profites




     


    Comme je l'ai dit avant, ce n'est pas en utilisant quelque chose de tout fait qu'on apprend. Qui a appris à  cuisiner en achetant des plat tout fait chez un traiteur...  ::)


     


    Quelqu'un a t'il une réponse qui pourrait m'aiguiller ?  ;)

  • Joanna CarterJoanna Carter Membre, Modérateur
    février 2017 modifié #22
    Tu n'as jamais utilisé UITableView ; ou voudrais-tu la réimplementer aussi ? Tu ne veux pas refaire le compilateur ?


    Les anglais ont un proverbe : "Why have a dog and bark youself?" (Porquoi être propriétaire d'un chien et se mettre à  aboyer soi-même ?)


    Tu as payé Apple pour ton ordi, tes iBidules et ton inscription développeur, pourquoi refaire UIKit toi-même ?


    Tu profiterais plus d'apprendre comment créer les agencements pour UICollectionViewController ; tu y trouveras pas mal de travail.
  • Joanna a pleinement raison pour le coup !


    C'est bien de vouloir apprendre de le sorte, on l'a tous fait, mais réinventer la roue n'est pas vraiment intéressant. Déjà  tu vas faire un framework qui fonctionnera d'office moins bien que les composants d'UIKit. De plus –et c'est ça qui est important– ça n'est pas intéressant de savoir faire ça dans son ensemble. 


     


    Je comprends que tu veuille apprendre à  gérer les gestures, les déplacements de vue, la gestion et le layout de ces meÌ‚mes vues. Le problème avec ta démarche c'est que tu t'attaque à  un très gros morceau. Gérer ce genre de chose fait appel un tas de composants et un diagramme des classes assez touffu dont tu n'as meÌ‚me pas idée. Je ne suis pas en train de dire que tu n'en n'es pas capable (j'en sais rien en fait) mais je pense qu'il y a des motifs plus sympas et plus didactiques pour apprendre et gagner de l'expérience en dev iOS.


     


    Continue ton application, maiÌ‚trise déjà  UICollectionView qui offre une API assez riche et tu vas trouver plein de choses plus marrantes à  faire par la suite. 


     


    Maintenant si ce que je dis ne te plaiÌ‚t pas –et tu as parfaitement le droit– je te conseillerai d'aller fouiller GitHub pour trouver des frameworks utilisés avant l'ère UICollectionView. Analyse le code et comprends le tu devrais déjaÌ€ en apprendre beaucoup meÌ‚me si analyser ce genre de code est plutoÌ‚t long et clairement chiant...

  • Dispatch_after te permet d'exécuter ci code après x secondes.
  • JérémyJérémy Membre
    février 2017 modifié #25


    Continue ton application, maiÌ‚trise déjà  UICollectionView qui offre une API assez riche et tu vas trouver plein de choses plus marrantes à  faire par la suite. 




     


    Le truc c'est que je ne suis pas en train de faire une application qui va utiliser ça. Non je ne compte pas créer de framework avec mes propres composants. Le but est de faire un exercice pour apprendre à  implémenter ce que je vous ai décrit. Ca ne va pas plus loin... Si effectivement je devais créer une app avec cette expérience utilisateur, il est évident que j'utiliserai l'UICollectionView.  :)


     




    Maintenant si ce que je dis ne te plaît pas




     


    Absolument pas, je comprends parfaitement ton point de vue.  :)


     




    Dispatch_after te permet d'exécuter ci code après x secondes.




     


    Ca marche, je vais regarder. Merci colas.  ;)


  • Il est bon de connaà®tre aussi pour ce genre d'actions reportées la classe NSInvocation.
  • Joanna CarterJoanna Carter Membre, Modérateur
    Ahem ! Avec UILongPressGestureRecognizer on peut changer le minimumPressDuration https://developer.apple.com/reference/uikit/uilongpressgesturerecognizer
  • JérémyJérémy Membre
    février 2017 modifié #28


    Dispatch_after te permet d'exécuter ci code après x secondes.




     


    D'acc !



    let deadlineTime = DispatchTime.now() + .seconds(1)
    DispatchQueue.main.asyncAfter(deadline: deadlineTime) {
    print("test")
    }

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