UIKit Dynamics adds a new level of features to the overall user
experience (UX) of iOS 7 apps. The API is, however, something to be used
sparingly and only when needed; otherwise, you might get user complaints about the bounciness of a table view or the
Lock Screen camera button, for example.

It’s simple to incorporate UIKit Dynamics into your iOS 7 app. Plus, the end result has a really big wow factor that is
certain to impress your users. Let’s take a quick conceptual drive around
UIKit Dynamics.

First, we adopt the protocol into the ViewController, which
will implement UIKit Dynamics. Why? Because the objects that will be animated in
the end will have to send back a lot of signals like “Hey, I collided with
a boundary” or “Hey, I just hit somebody else and I was going this
fast, in this direction.” In order to receive these messages, we use a
delegate and its callbacks.

 

@interface … <UICollisionBehaviorDelegate>

We need to create the view to animate and the property to
reference a UIDynamicAnimator, which is the object in charge of handling
animations in UIKit Dynamics.

 

@property (nonatomic, weak) IBOutlet UIView *square1;
@property (nonatomic) UIDynamicAnimator* animator;

Basically, we would prep all we need in viewDidLoad,
such as instantiating an animator to call the shots inside a particular
reference view. Then, we create a behavior or set of behaviors we wish to assign
to our animatable view. We define boundaries so we can keep our objects inside
a view. Finally, we add the behaviors to the animator and set the
viewcontroller as the delegate as well as set that animator object to our
property in order to hold a reference to it.

Now we sit back and get messages from the animator
and the animated view via the callbacks.

 

– (void)viewDidLoad
{
[super viewDidLoad];

UIDynamicAnimator* animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view];

UIGravityBehavior* gravityBeahvior = [[UIGravityBehavior alloc] initWithItems:@[self.square1]];
UICollisionBehavior* collisionBehavior = [[UICollisionBehavior alloc] initWithItems:@[self.square1]];
collisionBehavior.translatesReferenceBoundsIntoBoundary = YES;
[animator addBehavior:gravityBeahvior];
[animator addBehavior:collisionBehavior];
collisionBehavior.collisionDelegate = self;

self.animator = animator;
}

-(void)collisionBehavior:(UICollisionBehavior *)behavior beganContactForItem:(id<UIDynamicItem>)item withBoundaryIdentifier:(id<NSCopying>)identifier atPoint:(CGPoint)p
{
// Lighten the background color when the view is in contact with a boundary.
[(UIView*)item setBackgroundColor:[UIColor lightGrayColor]];
}

-(void)collisionBehavior:(UICollisionBehavior *)behavior endedContactForItem:(id<UIDynamicItem>)item withBoundaryIdentifier:(id<NSCopying>)identifier
{
// Restore the default color when ending a contcact.
[(UIView*)item setBackgroundColor:[UIColor grayColor]];
}

A simple example

Let’s say we are building a restaurant rating app. It’s a
single view app with a plain vanilla UIViewController that has these properties
connected to those outlets:

 

@property (nonatomic, strong) IBOutlet UILabel *restaurantName;
@property (nonatomic, strong) IBOutlet UILabel *restaurantAddress;

//STAR RATING
@property (nonatomic, strong) IBOutlet UIImageView *stars1;
@property (nonatomic, strong) IBOutlet UIImageView *stars2;
@property (nonatomic, strong) IBOutlet UIImageView *stars3;
@property (nonatomic, strong) IBOutlet UIImageView *stars4;
@property (nonatomic, strong) IBOutlet UIImageView *stars5;

Create the animator that will handle the animation inside
our viewDidLoad:

 

// Create animator
UIDynamicAnimator* animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view];

Add the views we want to animate to the behaviors we want to
implement:

 

//Create behaviors
UIGravityBehavior* gravityBeahvior = [[UIGravityBehavior alloc] initWithItems:@[self.stars1,self.stars2, self.stars3, self.stars4,self.stars5]];
UICollisionBehavior* collisionBehavior = [[UICollisionBehavior alloc] initWithItems:@[self.stars1,self.stars2, self.stars3, self.stars4,self.stars5]];

UIDynamicItemBehavior* propertiesBehavior = [[UIDynamicItemBehavior alloc] initWithItems:@[self.stars1,self.stars2, self.stars3, self.stars4,self.stars5]];
propertiesBehavior.elasticity = 5;

The last behavior is actually created to modify certain
physical properties of an object, in this case elasticity. There are other
properties we can modify in this manner.

We can also add specific boundaries, but in many cases we will
want to simply use the view’s edges as the natural boundaries, so we use this
line:

 

collisionBehavior.translatesReferenceBoundsIntoBoundary = YES;

Add the behaviors to the animator, set the delegate to
self, and reference our animator through its property:

 

[animator addBehavior:gravityBeahvior];
[animator addBehavior:collisionBehavior];

collisionBehavior.collisionDelegate = self;

self.animator = animator;

Finally, add the following delegate callbacks to decide what
gets done when a collision occurs:

 

-(void)collisionBehavior:(UICollisionBehavior *)behavior beganContactForItem:(id<UIDynamicItem>)item withBoundaryIdentifier:(id<NSCopying>)identifier atPoint:(CGPoint)p
{
// Lighten the background color when the view is in contact with a boundary.
[(UIView*)item setBackgroundColor:[UIColor lightGrayColor]];
}

-(void)collisionBehavior:(UICollisionBehavior *)behavior endedContactForItem:(id<UIDynamicItem>)item withBoundaryIdentifier:(id<NSCopying>)identifier
{
// Restore the default color when ending a contcact.
[(UIView*)item setBackgroundColor:[UIColor grayColor]];
}

That’s it! There are lots of neat effects you can use, but
don’t overdo it, or your users might complain that you gave them vertigo.