Home > Software engineering >  swift - chaining UIView animation
swift - chaining UIView animation

Time:09-19

I'd like to animate my UIImageView with these steps:

  1. scale 2 times
  2. scaled image movement

So I'm trying like this:

UIView.animate(withDuration: 0.5, animations: {
   self.imageView.transform = CGAffineTransform(scaleX: 2, y: 2)                        
}) { _ in                        
   UIView.animate(withDuration: 1.0, animations: {
        self.imageView.transform = CGAffineTransform(translationX: -50, y: -50)
                        
   }) { _ in

        //other steps
   }
 }

But the result is that before moving imageView got back to previous size and then moving. How to move scaled view?

also I've tried to change layer's anchorPoint inside the animate block with no success

And maybe there is more simple way to achieve my goal: ability to zoom out image, then focus at 3 custom points, then zoom in to the initial size.

CodePudding user response:

One approach is to put the start of an animation in the completion handler of the prior animation:

UIView.animate(withDuration: 1) { 
    // animation 1
} completion: { _ in
    UIView.animate(withDuration: 2) { 
        // animation 2
    } completion: {  _ in 
        UIView.animate(withDuration: 1) { 
            // animation 3
        } completion: {  _ in 
            // etc
        }
    }
}

If you want to avoid a tower of nested animations (each in the completion handler of the prior one), you can use a keyframe animation, e.g. this is a five second animation with three separate keyframes, each with a duration of one third of the total, and whose start time is set accordingly:

UIView.animateKeyframes(withDuration: 5, delay: 0) { 
    UIView.addKeyframe(withRelativeStartTime: 0, relativeDuration: 1 / 3) {
        // animation 1
    }
    
    UIView.addKeyframe(withRelativeStartTime: 1 / 3, relativeDuration: 1 / 3) {
        // animation 2
    }
    
    UIView.addKeyframe(withRelativeStartTime: 2 / 3, relativeDuration: 1 / 3) {
        // animation 3
    }
}

The above is for Swift 5.3 and later. For earlier versions, see previous revision of this answer.

CodePudding user response:

For your first question: Since you are assigning the transform to a new one without keeping the old configuration, so in your second animation, your view will transform to the default scale (1, 1). All you need is just assigning the transform to a new one which contains all the old configurations plus the new you want.

UIView.animate(withDuration: 0.5, animations: {
  self.button.transform = self.button.transform.scaledBy(x: 2, y: 2)
}) { _ in
  UIView.animate(withDuration: 1.0, animations: {
    self.button.transform = self.button.transform.translatedBy(x: -50, y: -50)
  }) { _ in
    
  }
}

It's even better if you use animateKeyframes

  • Related