28

I want to create an animation that will resize an UIView and its contents by a factor. Basically, I want to make an animation that first expands the view then shrinks it back to the original size.

What is the best way to do this? I tried CALayer.contentScale but it didn't do anything at all.

Flying_Banana
  • 2,707
  • 2
  • 18
  • 35
  • Related to http://stackoverflow.com/questions/5446899/scale-zoom-into-a-uiview-at-a-point or http://stackoverflow.com/questions/18329286/how-to-scale-zoom-a-uiview-to-a-given-cgpoint?lq=1? – tophyr Mar 14 '14 at 03:56

3 Answers3

60

You can nest some animation blocks together like so:

Objective-C:

[UIView animateWithDuration:1
                 animations:^{
                     yourView.transform = CGAffineTransformMakeScale(1.5, 1.5);
                 }
                 completion:^(BOOL finished) {
                     [UIView animateWithDuration:1
                                      animations:^{
                                          yourView.transform = CGAffineTransformIdentity;
                                          
                                      }];
                 }];

Swift 2:

UIView.animateWithDuration(1, animations: { () -> Void in
    yourView.transform = CGAffineTransformMakeScale(1.5, 1.5)
    }) { (finished: Bool) -> Void in
        UIView.animateWithDuration(1, animations: { () -> Void in
            yourView.transform = CGAffineTransformIdentity
        })}

Swift 3/4/5:

UIView.animate(withDuration: 1, animations: {
    yourView.transform = CGAffineTransform(scaleX: 1.5, y: 1.5)
}) { (finished) in
    UIView.animate(withDuration: 1, animations: { 
        yourView.transform = CGAffineTransform.identity
    })
}

and replacing the scale values and durations with your own.

JJC
  • 1,286
  • 10
  • 10
10

Here is a smaller approach that also loops:

[UIView animateWithDuration:1
                      delay:0
                    options:UIViewKeyframeAnimationOptionAutoreverse | UIViewKeyframeAnimationOptionRepeat
                 animations:^{
                     yourView.transform = CGAffineTransformMakeScale(1.5, 1.5);
                 }
                 completion:nil];

The option UIViewKeyframeAnimationOptionRepeat is what makes it loop, if you don't want it to keep "breathing". The animation block acts as the "inhale" and the UIViewKeyframeAnimationOptionAutoreverse option automatically plays the "exhale" animation.

ecnepsnai
  • 1,560
  • 4
  • 28
  • 51
5

Swift 5 UIView extension:

extension UIView {
    func pulse(withIntensity intensity: CGFloat, withDuration duration: Double, loop: Bool) {
        UIView.animate(withDuration: duration, delay: 0, options: [.repeat, .autoreverse], animations: {
            loop ? nil : UIView.setAnimationRepeatCount(1)
            self.transform = CGAffineTransform(scaleX: intensity, y: intensity)
        }) { (true) in
            self.transform = CGAffineTransform.identity
        }
    }
}

And then use the following:

yourView.pulse(withIntensity: 1.2, withDuration: 0.5, loop: true)

Just make sure you replace yourView with your own view.

Stephen Collins
  • 352
  • 4
  • 12