Flipcase Bounce In UIKit Dynamics

October 21, 2013

It was fun to make a little game like Flipcase with Dave in UIKit Dynamics. I have been blown away with the amount of press it has received, with many of the major tech and app blogs covering it. The YouTube video has received over 350k views.

I wanted to share how I created the physics in Flipcase to show how easy simple animations can be thanks to iOS 7 and UIKit Dynamics.

So here are the basic steps to recreate Flipcase:

Step 1 - Add a ball

Get setup by adding a simple circle to the screen when the user taps.

- (void)viewDidLoad
{
    [super viewDidLoad];

    // Simple tap gesture
    UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(onTap:)];
    [self.view addGestureRecognizer:tapGesture];
}

- (void)onTap:(UITapGestureRecognizer*)gesture
{
    if (gesture.state == UIGestureRecognizerStateEnded) {
        // Grab the x of the touch for the center of our ball
        // Ignore the y, we'll drop from the top
        CGPoint pt = [gesture locationInView:self.view];
        [self dropBallAtX:pt.x];
    }
}

- (void)dropBallAtX:(CGFloat)x
{
    // Create a ball and add it to our view
    UIView* ball = [[UIView alloc] initWithFrame:CGRectMake(x - (kBallSize/    2), 0, kBallSize, kBallSize)];
    ball.backgroundColor = [UIColor redColor];
    ball.layer.cornerRadius = kBallSize/2;
    ball.layer.masksToBounds = YES;
    [self.view addSubview:ball];
}        

Balls

Step 2 - Gravity

To get the balls to fall to the bottom of the screen we need to add gravity.

So we create an animator and a gravity behaviour.

- (void)viewDidLoad
{
    [super viewDidLoad];

    ....

    // Create our animator, we retain this ourselves
    self.animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view];

    // Gravity
    self.gravityBehavior = [[UIGravityBehavior alloc] initWithItems:@[ ]];
    self.gravityBehavior.magnitude = 10;
    [self.animator addBehavior:self.gravityBehavior];        
}        

Now let's attach the gravity after we create the ball:

- (void)dropBallAtX:(CGFloat)x
{
    // Create a ball and add it to our view
    UIView* ball = [[UIView alloc] initWithFrame:CGRectMake(x - (kBallSize/2), 0, kBallSize, kBallSize)];
    ball.backgroundColor = [UIColor redColor];
    ball.layer.cornerRadius = kBallSize/2;
    ball.layer.masksToBounds = YES;
    [self.view addSubview:ball];

    // Add some gravity
    [self.gravityBehavior addItem:ball];
}

Drop

Step 3 - Collision

We don't want the balls to drop off the bottom of the screen, we could just use the view bounds as a collision barrier, but let's also add a fake platform for them to stop on:

 - (void)viewDidLoad
{
    [super viewDidLoad];

    ....

    // Collision - make a fake platform
    self.collisionBehavior = [[UICollisionBehavior alloc] initWithItems:@[ ]];
    [self.collisionBehavior addBoundaryWithIdentifier:@"bottom"
                                       fromPoint:CGPointMake(0, 300)
                                         toPoint:CGPointMake(568, 300)];
    self.collisionBehavior.translatesReferenceBoundsIntoBoundary = YES;
    [self.animator addBehavior:self.collisionBehavior];        
}        

And again attach the behaviour:

- (void)dropBallAtX:(CGFloat)x
{
    ....

    // Add the collision
    [self.collisionBehavior addItem:ball];
}    

Collision

Step 4 - Bounce

To make it all a bit nicer we'll add a little bounce by using elasticity:

  - (void)viewDidLoad
{
    [super viewDidLoad];

    ....

    // Bounce!
    self.bounceBehaviour = [[UIDynamicItemBehavior alloc] initWithItems:@[ ]];
    self.bounceBehaviour.elasticity = 0.6;
    [self.animator addBehavior:self.bounceBehaviour];   
}     

And again attach it:

- (void)dropBallAtX:(CGFloat)x
{
    ....

    // Add the bounce
    [self.bounceBehaviour addItem:ball];
}    

Bounce

Step 5

That's it! Let's have a little fun with it:

Have Fun

  • Note : it gets pretty slow and clunky when you start adding too many objects to the screen.

You can find the full working code on Github here.

If this helps you make something fun I'd love to hear about it Tweet me.

Get Monthly Updates On Mobile Dev

Join over 2,000 other mobile devs.

No spam, promise!

Get Monthly Updates On Mobile Dev

Join over 2,000 other mobile devs.

No spam, promise!