Aller au contenu


Photo

Connaître la position d’une vue pendant une animation


  • Please log in to reply
8 réponses à ce sujet

#1 Draken

Draken

    Mouleur de chocolats

  • Artisan chocolatier
  • PipPipPipPipPipPipPipPip
  • 8 598 messages
  • LocationParis

Posté 06 juillet 2017 - 16:56

En jouant avec UIView.animate() je me suis aperçu d’un truc curieux, il est impossible de connaître la position d’une vue pendant une animation de mouvement.

 

Pour tester ça, j’ai écrit une mini application déplaçant une barre verticale de droite à gauche.

import UIKit

class Rectangle : UIView {
    
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        print ("touchesBegan")
    }
    
    
}

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        
        self.view.tag = 1
        
        let sizeEcran = self.view.bounds.size
        
        /*
        let vueRouge = UIView(frame: CGRect(x: 0,
                                            y: 0,
                                            width: sizeEcran.width*0.4,
                                            height: sizeEcran.height))
        */
        let vueRouge = Rectangle(frame: CGRect(x: 0,
                                            y: 0,
                                            width: sizeEcran.width*0.4,
                                            height: sizeEcran.height))
        
        vueRouge.backgroundColor = UIColor.red
        self.view.addSubview(vueRouge)
        vueRouge.tag = 42
        
        let pointDestination = CGPoint(x: sizeEcran.width-vueRouge.bounds.width*0.5,
                                       y: sizeEcran.height*0.5)
        
        UIView.animate(withDuration: 2.0,
                       delay: 0,
                       options: [.repeat,
                                 .autoreverse,
                                 .curveLinear,
                                 .allowUserInteraction],
                       animations: { vueRouge.center = pointDestination },
                       completion: nil)
    }
    
    
    @IBAction func actionTap(_ sender: UITapGestureRecognizer) {
        let pos = sender.location(in: self.view)
        
        /*
        if let vueDetection = self.view.hitTest(pos, with: nil) {
            print ("Tag : ", vueDetection.tag)
        }
        */
        
        if let test = detectionVue(vue: self.view, position: pos) {
            print ("Tag : ", test.tag)
        }
    }
    
    
    func detectionVue(vue:UIView, position:CGPoint) -> UIView? {
        for subView in vue.subviews {
            if !subView.isHidden {
                print ("subview (tag ",subView.tag, ") : ", subView.frame)
            }
        }
        return nil
    }
}

Une gesture définie dans le Storyboard appelle la fonction actionTap() quand l’utilisateur touche l’écran. 

 

Normalement les interactions utilisateurs sont désactivés pendant les animations, mais j’ai utilisé le paramètre .allowUserInteraction pour les réactiver. J’ai d’abord utiliser hitTest(), puis j’ai écrit une fonction spécialisée allant lire les subviews de l’écran pour tester individuellement chaque vue. Ensuite j’ai tenté de sous-classer la vue. Le code en haut est un peu bordélique à cause de tous ces essais.

 

Conclusion : pendant une animation de mouvement, le système considère que la vue est TOUJOURS A SA POSITION FINALE. Quelque soit la position visible de la barre pendant l'animation, pour UIKit elle est à droite de l’écran

 

Comme vous pouvez avec les relevés de position suivants, UIKit ne semble pas savoir que la barre se balade sur l’écran, alors que j’ai lu la position à différents moments de l’animation.

 

 

subview (tag  42 ) :  (192.0, 0.0, 128.0, 568.0)

subview (tag  42 ) :  (192.0, 0.0, 128.0, 568.0)

subview (tag  42 ) :  (192.0, 0.0, 128.0, 568.0)

subview (tag  42 ) :  (192.0, 0.0, 128.0, 568.0)

subview (tag  42 ) :  (192.0, 0.0, 128.0, 568.0)

subview (tag  42 ) :  (192.0, 0.0, 128.0, 568.0)

subview (tag  42 ) :  (192.0, 0.0, 128.0, 568.0)

subview (tag  42 ) :  (192.0, 0.0, 128.0, 568.0)

subview (tag  42 ) :  (192.0, 0.0, 128.0, 568.0)

subview (tag  42 ) :  (192.0, 0.0, 128.0, 568.0)

subview (tag  42 ) :  (192.0, 0.0, 128.0, 568.0)

subview (tag  42 ) :  (192.0, 0.0, 128.0, 568.0)

subview (tag  42 ) :  (192.0, 0.0, 128.0, 568.0)

subview (tag  42 ) :  (192.0, 0.0, 128.0, 568.0)

 

Je ne sais pas comment UIKit se débrouille pour gérer les animations, mais en tout cas il cache bien l’information de position. La vue semble toujours au même endroit, le layer aussi. 

 

Quelqu’un a une suggestion sur la manière de lire la position de l’animation à un moment t ?

Fichier(s) joint(s)

  • Fichier joint  barre.png   9,37 Ko   0 téléchargement(s)

Garçon, servez-moi un Covfefe avec du lait de soja, sans OGM ..

Et faites régler la climatisation, il fait bien chaud, ici !

 

 

Éternel Novice !  :baby:

Tueur de poneys !  :(

 

Faire simple .. c'est compliqué !

Faire compliqué .. c'est simple !

 

Un MOOC (cours en ligne - dont je ne suis pas l'auteur) gratuit sur la programmation en Obj-C et en Swift 3, démarrant le 14 Mars 2017 :

https://www.edx.org/...onnex-progios1x

 

Des dizaines d'heures de tutoriels vidéo en français (je ne suis pas l'auteur) pour apprendre à développer en Obj-C et Swift : http://pagesperso-sy...don/5I452-2014/

 

 


#2 Larme

Larme

    Broyeur de fèves

  • Artisan chocolatier
  • PipPipPipPipPipPip
  • 1 949 messages
  • LocationParis

Posté 06 juillet 2017 - 17:19

https://stackoverflo...uring-animation ?
=> view.layer.presentation.frame ?


  • Draken aime ceci
Tant que vous avez des dents, mangez des pommes. Tant que vous avez de l'argent, croquez la Pomme.

#3 Draken

Draken

    Mouleur de chocolats

  • Artisan chocolatier
  • PipPipPipPipPipPipPipPip
  • 8 598 messages
  • LocationParis

Posté 06 juillet 2017 - 17:41

YEEEEES ça marche !!!  :prie!:

 

Ceci dit, je ne comprend pas pourquoi view.layer.bounds donne une information (très) différente de view.layer.presentation().frame.


Garçon, servez-moi un Covfefe avec du lait de soja, sans OGM ..

Et faites régler la climatisation, il fait bien chaud, ici !

 

 

Éternel Novice !  :baby:

Tueur de poneys !  :(

 

Faire simple .. c'est compliqué !

Faire compliqué .. c'est simple !

 

Un MOOC (cours en ligne - dont je ne suis pas l'auteur) gratuit sur la programmation en Obj-C et en Swift 3, démarrant le 14 Mars 2017 :

https://www.edx.org/...onnex-progios1x

 

Des dizaines d'heures de tutoriels vidéo en français (je ne suis pas l'auteur) pour apprendre à développer en Obj-C et Swift : http://pagesperso-sy...don/5I452-2014/

 

 


#4 Joanna Carter

Joanna Carter

    Broyeur de fèves

  • Contrôleur d'arômes
  • 1 887 messages
  • LocationPlestin-les-Grèves (22)

Posté 06 juillet 2017 - 18:12

J'ai trouvé ceci :

 

https://www.invasive...170684814453125

 

ça t'intéresse ?


  • Draken aime ceci

#5 Draken

Draken

    Mouleur de chocolats

  • Artisan chocolatier
  • PipPipPipPipPipPipPipPip
  • 8 598 messages
  • LocationParis

Posté 06 juillet 2017 - 18:19

Oui, c’est sacrément intéressant. Y compris la possibilité de définir des trajectoires d’animation avec des courbes complexes. Merci nounours !


Garçon, servez-moi un Covfefe avec du lait de soja, sans OGM ..

Et faites régler la climatisation, il fait bien chaud, ici !

 

 

Éternel Novice !  :baby:

Tueur de poneys !  :(

 

Faire simple .. c'est compliqué !

Faire compliqué .. c'est simple !

 

Un MOOC (cours en ligne - dont je ne suis pas l'auteur) gratuit sur la programmation en Obj-C et en Swift 3, démarrant le 14 Mars 2017 :

https://www.edx.org/...onnex-progios1x

 

Des dizaines d'heures de tutoriels vidéo en français (je ne suis pas l'auteur) pour apprendre à développer en Obj-C et Swift : http://pagesperso-sy...don/5I452-2014/

 

 


#6 Joanna Carter

Joanna Carter

    Broyeur de fèves

  • Contrôleur d'arômes
  • 1 887 messages
  • LocationPlestin-les-Grèves (22)

Posté 06 juillet 2017 - 18:20

Et ceci :

 

http://jamesonquave....10-and-swift-3/

 

:-*



#7 Draken

Draken

    Mouleur de chocolats

  • Artisan chocolatier
  • PipPipPipPipPipPipPipPip
  • 8 598 messages
  • LocationParis

Posté 06 juillet 2017 - 18:28

Eh bien, je vais avoir de quoi lire ce soir ..  :bravo!:

C’est sympa de voir qu’iOS 10 intègre une nouvelle API d’animation (UIViewPropertyAnimator) pour pallier aux limitations de l’ancien système, UIView.animate() apparu avec iOS 4.0, qui commençait à marquer son âge. Il était temps d’avoir un peu de sang neuf.


Garçon, servez-moi un Covfefe avec du lait de soja, sans OGM ..

Et faites régler la climatisation, il fait bien chaud, ici !

 

 

Éternel Novice !  :baby:

Tueur de poneys !  :(

 

Faire simple .. c'est compliqué !

Faire compliqué .. c'est simple !

 

Un MOOC (cours en ligne - dont je ne suis pas l'auteur) gratuit sur la programmation en Obj-C et en Swift 3, démarrant le 14 Mars 2017 :

https://www.edx.org/...onnex-progios1x

 

Des dizaines d'heures de tutoriels vidéo en français (je ne suis pas l'auteur) pour apprendre à développer en Obj-C et Swift : http://pagesperso-sy...don/5I452-2014/

 

 


#8 Draken

Draken

    Mouleur de chocolats

  • Artisan chocolatier
  • PipPipPipPipPipPipPipPip
  • 8 598 messages
  • LocationParis

Posté 06 juillet 2017 - 20:52

La nouvelle API a une propriété pour activer le hitTesting. Sympa ..

var isManualHitTestingEnabled: Bool { get set }

La doc complète ici : https://developer.ap...ropertyanimator

 

On peut aussi mettre une animation sur pause. Pratique ..


Garçon, servez-moi un Covfefe avec du lait de soja, sans OGM ..

Et faites régler la climatisation, il fait bien chaud, ici !

 

 

Éternel Novice !  :baby:

Tueur de poneys !  :(

 

Faire simple .. c'est compliqué !

Faire compliqué .. c'est simple !

 

Un MOOC (cours en ligne - dont je ne suis pas l'auteur) gratuit sur la programmation en Obj-C et en Swift 3, démarrant le 14 Mars 2017 :

https://www.edx.org/...onnex-progios1x

 

Des dizaines d'heures de tutoriels vidéo en français (je ne suis pas l'auteur) pour apprendre à développer en Obj-C et Swift : http://pagesperso-sy...don/5I452-2014/

 

 


#9 Draken

Draken

    Mouleur de chocolats

  • Artisan chocolatier
  • PipPipPipPipPipPipPipPip
  • 8 598 messages
  • LocationParis

Posté 06 juillet 2017 - 23:50

Voici le programme corrigé, avec détection d’une vue avec une animation de mouvement, basé sur la nouvelle API UIViewPropertyAnimator. A la différence que l’animation de la barre rouge n’est pas permanente. Je n’ai pas trouvé le moyen de répéter une animation à l’infini. Le paramètre .repeat de l’ancienne API ne fonctionne pas. L’animation est exécutée 1000 fois, ce qui est suffisant pour les tests.

import UIKit

class ViewController: UIViewController {
    
    let vueRouge = UIView()

    override func viewDidLoad() {
        super.viewDidLoad()
        
        self.view.tag = 1
        
        let sizeEcran = self.view.bounds.size
        
        vueRouge.frame = CGRect(x: 0,
                                y: 0,
                                width: sizeEcran.width*0.4,
                                height: sizeEcran.height)
        
        vueRouge.backgroundColor = UIColor.red
        self.view.addSubview(vueRouge)
        vueRouge.tag = 42
        
        let pointDestination = CGPoint(x: sizeEcran.width-vueRouge.bounds.width*0.5,
                                       y: sizeEcran.height*0.5)
        
        // Création animation
        let animation = UIViewPropertyAnimator(
            duration: 2.0,
            curve: .linear,
            animations: {
                UIView.setAnimationRepeatCount(1000)
                UIView.setAnimationRepeatAutoreverses(true)
                self.vueRouge.center = pointDestination } )
        
        animation.startAnimation()
     }
    
    
    @IBAction func actionTap(_ sender: UITapGestureRecognizer) {
        let pos = sender.location(in: self.view)
        
        if let vueDetection = self.view.hitTest(pos, with: nil) {
            print ("Tag : ", vueDetection.tag)
        }
        
     }
    
}


Le tag 1 est associé à l’écran vide, la valeur 42 à la barre en mouvement !

 

 

Tag :  1

Tag :  42

Tag :  1

Tag :  42

Tag :  1

Tag :  1

Tag :  42

Tag :  1

Tag :  42

Tag :  42

Tag :  42

Tag :  42

Tag :  1

Tag :  1

Tag :  42

 

Garçon, servez-moi un Covfefe avec du lait de soja, sans OGM ..

Et faites régler la climatisation, il fait bien chaud, ici !

 

 

Éternel Novice !  :baby:

Tueur de poneys !  :(

 

Faire simple .. c'est compliqué !

Faire compliqué .. c'est simple !

 

Un MOOC (cours en ligne - dont je ne suis pas l'auteur) gratuit sur la programmation en Obj-C et en Swift 3, démarrant le 14 Mars 2017 :

https://www.edx.org/...onnex-progios1x

 

Des dizaines d'heures de tutoriels vidéo en français (je ne suis pas l'auteur) pour apprendre à développer en Obj-C et Swift : http://pagesperso-sy...don/5I452-2014/

 

 





0 utilisateur(s) li(sen)t ce sujet

0 membre(s), 0 invité(s), 0 utilisateur(s) anonyme(s)