Executer du code de façon asynchrone

Bonsoir à  tous,


 


j'ai une vue tout simple avec 3 images. Sur chacune, je joue une petite animation simple up and down de 10px vers le haut. ça fonctionne.


Sauf que je voudrais que la deuxième image s'anime à  la fin de la première et la troisième à  la fin de deuxième, le code ci-dessous devrait s'exécuter pas à  pas : image1 puis image2 puis image3.


En l'état les 3 images bougent ensemble. Que puis-je faire ? j'ai essayé des dispatch_queue en mode async, etc... mais en vain.


 


Merci pour votre aide.



override func viewDidAppear(_ animated: Bool) {
let hover = CABasicAnimation(keyPath: "position")

hover.isAdditive = true
hover.fromValue = NSValue(cgPoint: CGPoint.zero)
hover.toValue = NSValue(cgPoint: CGPoint(x: 0.0, y: -10.0))
hover.autoreverses = true
hover.duration = 0.2
hover.repeatCount = 1

self.image1.layer.add(hover, forKey: "myHoverAnimation")
self.image2.layer.add(hover, forKey: "myHoverAnimation")
self.image3.layer.add(hover, forKey: "myHoverAnimation")

}


Réponses

  • Pourquoi ne pas utiliser la complétion de fin de UIView.animate, pour déclencher les animations les unes après les autres ?



    import UIKit

    class ViewController: UIViewController {

    @IBOutlet weak var vue1: UIView!
    @IBOutlet weak var vue2: UIView!
    @IBOutlet weak var vue3: UIView!

    override func viewDidLoad() {
    super.viewDidLoad()
    }

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {

    let decalage:CGFloat = -50

    UIView.animate(withDuration: 0.5,
    animations: { self.vue1.frame.origin.y += decalage },
    completion: { _ in
    UIView.animate(withDuration: 0.5,
    animations: { self.vue2.frame.origin.y += decalage },
    completion: { _ in
    UIView.animate(withDuration: 0.5,
    animations: { self.vue3.frame.origin.y += decalage })
    }) })
    }
    }
  • CéroceCéroce Membre, Modérateur

    Je suis d'accord avec Draken. Si tu veux vraiment utiliser Core Animation, CATransaction a une propriété .completionBlock.


  • Bonsoir, merci pour vos réponses.


    En ce qui concerne les animations, je suis tombé sur ce tuto qui propose d'utiliser la notion de "delay" et cela correspond plus à  ce que j'imaginais faire au final : insérer un léger décalage entre les animations.


     


    https://www.raywenderlich.com/173544/ios-animation-tutorial-getting-started-3



    UIView.animate(withDuration: 0.5, delay: 0.3, options: [],
    animations: {
    self.username.center.x += self.view.bounds.width
    },
    completion: nil
    )
  • Absolument. J'y avais pensé, mais vu le titre du topic j'ai préféré te montrer une solution avec un vrai synchronisme du code.


     


    L'utilisation d'un délai permet un synchronisme apparent des mouvements, mais ils sont complètements indépendants les uns des autres. Si tu te trompes dans un paramètre temporel, toute la chorégraphie est fichue.



  •  


    Bonsoir, merci pour vos réponses.


    En ce qui concerne les animations, je suis tombé sur ce tuto qui propose d'utiliser la notion de "delay" et cela correspond plus à  ce que j'imaginais faire au final : insérer un léger décalage entre les animations.


     


    https://www.raywenderlich.com/173544/ios-animation-tutorial-getting-started-3



    UIView.animate(withDuration: 0.5, delay: 0.3, options: [],
    animations: {
    self.username.center.x += self.view.bounds.width
    },
    completion: nil
    )



    a


    En fait, tu n'as pas besoin d'employer une syntaxe aussi complexe. options: et completion: ont une valeur vide par défaut, ce qui évite d'avoir à  les définir dans le code.


     


    La syntaxe simplifiée est plus parlante, enfin à  mes yeux :



    let anim = { self.vue1.frame.origin.y += decalage }
    UIView.animate(withDuration: 0.5, delay: 0.3, animations: anim)


  •  


    a


    En fait, tu n'as pas besoin d'employer une syntaxe aussi complexe. options: et completion: ont une valeur vide par défaut, ce qui évite d'avoir à  les définir dans le code.


     


    La syntaxe simplifiée est plus parlante, enfin à  mes yeux :



    let anim = { self.vue1.frame.origin.y += decalage }
    UIView.animate(withDuration: 0.5, delay: 0.3, animations: anim)



    J'ai compris. Merci Draken

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