Search code examples
swiftanimationuiimageviewtransitionuipangesturerecognizer

Swift 5.4 UIImage animation: How to switch from bouncing (UIViewAnimate) to dragging (UIPanGestureRecognizer)


I have a UIImageView.

I can either get it bouncing by using animate:

        self.myImage.frame = CGRect(x: myImage.center.x, y: myImage.center.y, width: 50, height: 70)
        UIView.animate(withDuration: 0.4, delay: 0, options: [.repeat, .autoreverse] , animations: {
            self.myImage.frame = CGRect(x: self.myImage.center.x, y: self.myImage.center.y, width: 70, height: 80);
            }) { (completed) in  }

or, I can drag it by using panGestureRecogniser:

    @IBAction func dragView(_ sender: UIPanGestureRecognizer) {
            let translation = sender.translation(in: self.view)
            if let viewToDrag = sender.view {
                viewToDrag.center = CGPoint(x: viewToDrag.center.x + translation.x, y: viewToDrag.center.y + translation.y)
                sender.setTranslation(.zero, in: viewToDrag)
            }

How do I switch from first bouncing and then to dragging?


Solution

  • Add .allowUserInteraction to your options when setting up the animation

    self.myImage.frame = CGRect(x: myImage.center.x, y: myImage.center.y, width: 50, height: 70)
    UIView.animate(withDuration: 0.4, delay: 0, options: [.repeat, .autoreverse, .allowUserInteraction] , animations: {
      self.myImage.frame = CGRect(x: self.myImage.center.x, y: self.myImage.center.y, width: 70, height: 80);
      }) { (completed) in  }
    

    EDIT: to break the bouncing animation loop use self.myImage.layer.removeAllAnimations() in the beginning state of the pan gesture like so:

    @IBAction func dragView(_ sender: UIPanGestureRecognizer) {
                let translation = sender.translation(in: self.view)
                if let viewToDrag = sender.view {
                    if sender.state == .began {
                       viewToDrag.layer.removeAllAnimations()
                    }
                    viewToDrag.center = CGPoint(x: viewToDrag.center.x + translation.x, y: viewToDrag.center.y + translation.y)
                    sender.setTranslation(.zero, in: viewToDrag)
                }