36

Is there a way to animate a view so that it zooms up and kinda goes a bit too far and rubberbands back to the final size? I'm unsure how to do this sort of animation.

Andrew
  • 15,935
  • 28
  • 121
  • 203

10 Answers10

111

write this code when you want to trigger this animation

popUp.transform = CGAffineTransformScale(CGAffineTransformIdentity, 0.001, 0.001);

[self.view addSubview:popUp];

[UIView animateWithDuration:0.3/1.5 animations:^{
    popUp.transform = CGAffineTransformScale(CGAffineTransformIdentity, 1.1, 1.1);
} completion:^(BOOL finished) {
    [UIView animateWithDuration:0.3/2 animations:^{
        popUp.transform = CGAffineTransformScale(CGAffineTransformIdentity, 0.9, 0.9);
    } completion:^(BOOL finished) {
        [UIView animateWithDuration:0.3/2 animations:^{
            popUp.transform = CGAffineTransformIdentity;                            
        }];
    }];
}];

SWIFT 5.0

    selectView.transform =
        CGAffineTransform.identity.scaledBy(x: 0.001, y: 0.001)

    view.addSubview(selectView)

    UIView.animate(withDuration: 0.3 / 1.5, animations: {
        selectView.transform =
            CGAffineTransform.identity.scaledBy(x: 1.1, y: 1.1)
    }) { finished in
        UIView.animate(withDuration: 0.3 / 2, animations: {
            selectView.transform = .identity.scaledBy(x: 0.9, y: 0.9)
        }) { finished in
            UIView.animate(withDuration: 0.3 / 2, animations: {
                selectView.transform = CGAffineTransform.identity
            })
        }
    }

This is updated code (from fabio.cionini) as it is accepted answer so updating to latest.

Krunal Nagvadia
  • 1,083
  • 2
  • 12
  • 33
Amit Singh
  • 8,383
  • 4
  • 28
  • 31
  • this is the right code to bounce and zoom type animation you can also find this code in the Facbook API,the old facebook api..... – Sabby May 26 '11 at 08:59
  • Just to add to the conversation you can change the point of animation like: popUp.center=CGPointMake(0,0) and inside your animation block: popUp.center=self.view.center This will create the illusion that popUp is coming from the edges of the view and centers itself inside your view... – George Asda Jan 29 '14 at 09:04
  • very useful. Thank you. – Yucel Bayram Jul 31 '15 at 08:15
  • 2
    awesome, thanks. I was able to add a cool heart-pop animation for likes on images (instagram-ish) in under two minutes using this! – Adam G Oct 27 '15 at 02:12
  • Super... Thank you very much – Augustine P A Jun 02 '16 at 06:20
46

Just refactored the code by Amit Singh using blocks, which makes it much simpler and readable.

popUp.transform = CGAffineTransformScale(CGAffineTransformIdentity, 0.001, 0.001);

[self.view addSubview:popUp];

[UIView animateWithDuration:0.3/1.5 animations:^{
    popUp.transform = CGAffineTransformScale(CGAffineTransformIdentity, 1.1, 1.1);
} completion:^(BOOL finished) {
    [UIView animateWithDuration:0.3/2 animations:^{
        popUp.transform = CGAffineTransformScale(CGAffineTransformIdentity, 0.9, 0.9);
    } completion:^(BOOL finished) {
        [UIView animateWithDuration:0.3/2 animations:^{
            popUp.transform = CGAffineTransformIdentity;                            
        }];
    }];
}];
Fabio Cionini
  • 767
  • 6
  • 15
21

Too many complicated answers . It's much easier to do it as of 2017 (Swift 3/4).

Swift 4-

yourview.transform = yourview.transform.scaledBy(x: 0.001, y: 0.001)

UIView.animate(withDuration: 0.5, delay: 0.0, usingSpringWithDamping: 0.5, initialSpringVelocity: 0.3, options: .curveEaseInOut, animations: {
      yourview.transform = CGAffineTransform.identity.scaledBy(x: 1.0, y: 1.0)
  }, completion: nil)

Note the usingSpringWithDamping parameter. This parameter dictates how much bounce/spring effect you want and allows values from 0 to 1. The lower the value the more the bounce effect. Also, if you do not like the scaleBy effect then you can simply use good old frames to show a expanding and bouncing UIView.

Anjan Biswas
  • 7,746
  • 5
  • 47
  • 77
  • I went this route too. Curious why you used `.curveEaseInOut`, doesn't using the animation curve of a physical spring mean you don't use the easeInOut curve? Seems pointless – xaphod Jan 05 '18 at 17:02
  • `CGAffineTransform.identity.scaleBy(1, 1)` is equivalent of `CGAffineTransform.identity` – mojuba Feb 21 '19 at 15:33
  • This spring animation is worked in Swift 5 too. – Zhou Haibo Aug 13 '21 at 16:41
8

This can be done in a much simpler way these days:

view.transform = CGAffineTransformScale(CGAffineTransformIdentity, 0.001, 0.001);
[UIView animateWithDuration:0.5 delay:0.2 usingSpringWithDamping:0.6f initialSpringVelocity:1.f options:UIViewAnimationOptionCurveEaseInOut animations:^{
    view.transform = CGAffineTransformScale(CGAffineTransformIdentity, 1.0, 1.0);
} completion:^(BOOL finished) {
    view.transform = CGAffineTransformIdentity;
}];
mattsson
  • 1,329
  • 1
  • 14
  • 30
6

Amit's answer is nice and accepted one. I am posting the Swift version of that answer over here for someone who wants to develop in Swift/future. I have used Xcode 7.3.1 and Swift 2.2 to develop this.

popView.transform = CGAffineTransformScale(CGAffineTransformIdentity, 0.001, 0.001)
self.view.addSubview(popView)
UIView.animateWithDuration(0.3/1.0, animations: {
    popView.transform = CGAffineTransformScale(CGAffineTransformIdentity, 1.1, 1.1)
    }, completion: {finished in
      UIView.animateWithDuration(0.3/1.2, animations: {
          popView.transform = CGAffineTransformScale(CGAffineTransformIdentity, 0.9, 0.9);
          }, completion: {finished in
            UIView.animateWithDuration(0.3/1.5, animations: {
               popView.transform = CGAffineTransformIdentity
              })
       })
})

Thanks and please do comment for update.

UPDATE Here is the same code for Swift 3. Works well with Xcode 8 and iOS 10.

let identityAnimation = CGAffineTransform.identity
let scaleOfIdentity = identityAnimation.scaledBy(x: 0.001, y: 0.001)
popView.transform = scaleOfIdentity
self.view.addSubview(popView)
UIView.animate(withDuration: 0.3/1.5, animations: {
    let scaleOfIdentity = identityAnimation.scaledBy(x: 1.1, y: 1.1)
    popView.transform = scaleOfIdentity
    }, completion: {finished in
        UIView.animate(withDuration: 0.3/2, animations: {
                let scaleOfIdentity = identityAnimation.scaledBy(x: 0.9, y: 0.9)
                popView.transform = scaleOfIdentity
                }, completion: {finished in
                    UIView.animate(withDuration: 0.3/2, animations: {
                        popView.transform = identityAnimation
                    })
                })
            })

Hope this helped.

onCompletion
  • 6,500
  • 4
  • 28
  • 37
5

Just for future code reuse and keeping code clean.

@interface UIView (Animation)
   - (void)addSubviewWithBounce:(UIView*)theView;


@implementation UIView (Animation)

-(void)addSubviewWithBounce:(UIView*)theView
{
   theView.transform = CGAffineTransformScale(CGAffineTransformIdentity, 0.001, 0.001);

                        [self addSubview:theView];

                        [UIView animateWithDuration:0.3/1.5 animations:^{
                            theView.transform = CGAffineTransformScale(CGAffineTransformIdentity, 1.1, 1.1);
                        } completion:^(BOOL finished) {
                            [UIView animateWithDuration:0.3/2 animations:^{
                                theView.transform = CGAffineTransformScale(CGAffineTransformIdentity, 0.9, 0.9);
                            } completion:^(BOOL finished) {
                                [UIView animateWithDuration:0.3/2 animations:^{
                                    theView.transform = CGAffineTransformIdentity;
                                }];
                            }];
                        }];
}

@end
Luke
  • 3,375
  • 2
  • 22
  • 22
  • how do I hide it with the same animation? –  Jan 16 '14 at 18:24
  • @Gabriel Molter: just reverse the animation above with the last block being the: popUp.transform = CGAffineTransformScale(CGAffineTransformIdentity, 0.001, 0.001); – George Asda Jan 29 '14 at 09:07
1

Use following code for zoom bouncing animation.

 #define DURATION 1.0

CAKeyframeAnimation *animation = [CAKeyframeAnimation
                                  animationWithKeyPath:@"transform"];

CATransform3D scale1 = CATransform3DMakeScale(0.5, 0.5, 1);
CATransform3D scale2 = CATransform3DMakeScale(1.2, 1.2, 1);
CATransform3D scale3 = CATransform3DMakeScale(0.9, 0.9, 1);
CATransform3D scale4 = CATransform3DMakeScale(1.0, 1.0, 1);

NSArray *frameValues = [NSArray arrayWithObjects:
                        [NSValue valueWithCATransform3D:scale1],
                        [NSValue valueWithCATransform3D:scale2],
                        [NSValue valueWithCATransform3D:scale3],
                        [NSValue valueWithCATransform3D:scale4],
                        nil];
[animation setValues:frameValues];

NSArray *frameTimes = [NSArray arrayWithObjects:
                       [NSNumber numberWithFloat:0.0],
                       [NSNumber numberWithFloat:0.5],
                       [NSNumber numberWithFloat:0.9],
                       [NSNumber numberWithFloat:1.0],
                       nil];
[animation setKeyTimes:frameTimes];

animation.fillMode = kCAFillModeForwards;
animation.removedOnCompletion = NO;
animation.duration = DURATION;
[animationView.layer addAnimation:animation forKey:@"popup"];
Piyush
  • 1,156
  • 12
  • 20
1

Used with iOS9 and xCode 7

//for zoom in
    [UIView animateWithDuration:0.5f animations:^{

        self.sendButton.transform = CGAffineTransformMakeScale(1.5, 1.5);
    } completion:^(BOOL finished){}];
// for zoom out
        [UIView animateWithDuration:0.5f animations:^{

            self.sendButton.transform = CGAffineTransformMakeScale(1, 1);
        }completion:^(BOOL finished){}];
Ahmed Abdallah
  • 2,338
  • 1
  • 19
  • 30
0

Check the animation related section in UIView Class Reference in your Xcode. Hint: use transform property.

cxa
  • 4,238
  • 26
  • 40
0

Swift 5

With a callback on completion.

    func bounceIn(_ callBack: @escaping ()->()) {
        let scaleTransform = CGAffineTransform(scaleX: 0.0, y: 0.0)
        self.transform = scaleTransform
        UIView.animate(
            withDuration: 0.5,
            usingSpringWithDamping: 0.4,
            initialSpringVelocity: 0.4,
            options: [UIView.AnimationOptions.curveLinear],
            animations: { [weak self] in
                 self?.transform = CGAffineTransform(scaleX: 1.0, y: 1.0)
            },
            completion: { (finished: Bool) -> Void in
                callBack()
        })
    }

Use:

    bounceIn() {
        // doStuff when animation is complete
    }
Adrian Bartholomew
  • 2,506
  • 6
  • 29
  • 37