[UIKit Dynamics Series] How to make custom UIView animations with UISnapBehavior and UIDynamicItemBehavior

UIKit Dynamics is the UIKit engine that provides physics-related capabilities and animations to views and other UI items. Thanks to a powerful set of API, classes and protocols, the engine provides more advanced animations that help to make your app more springy and attractive.

In this tutorial, you will learn how to use the technology behind the UIKit Dynamics to animate your app views in a fancy way. Along the way, you will learn how to use the UISnapBehavior and the UIDynamicItemBehavior classes to define and manage the way and context in which views will perform the animations.

Without further ado, let’s do some animations 🙂

Download the starter project here, open it, and select Main.storyboard from the Project navigator view.

The scene contains two UI controls, an image view and a button to dismiss the screen content and move the controls off screen with some fancy animations.

If you run the project, the views are still frozen and do nothing. Let’s put in some code to get them to work.

Select ViewController.swift file from the Project navigator to open it in the editor. You will notice both outlets are already hooked up to the code. Let’s start by declaring some properties that you will need later.

Place the following declarations below the class name:

var iconAnimator:UIDynamicAnimator!
var btnAnimator: UIDynamicAnimator!

Both properties declared above are UIDynamicAnimator types, this class objects will provide all physics animations related to their attached items. In this case, the items are the button and the image view 🙂

Next, locate the dismissAction method and copy the following code inside:

//1
iconAnimator = UIDynamicAnimator(referenceView: icon)
iconAnimator.removeAllBehaviors()
//2
let iconDestinationPoint: CGPoint = CGPoint(x: -20, y: -300)
//3
let snapBehavior = UISnapBehavior(item: icon, snapToPoint: iconDestinationPoint)
snapBehavior.damping = 20.0
//4
iconAnimator.addBehavior(snapBehavior)

Let’s explain the code above in details:

//1 : Here you initialised the UIDynamicAnimator property, this object will manage the context and the behavior of the animation. In this case, the animated view will be the icon image view, so you just passed it in argument as the referenced view by the animator object.

//2 : Here you defined the new coordinate of the icon after the animation will finish, the point coordinates are explicitly set to be off screen.

//3: This is the main part, after you set up the animator object, you need to define a behavior to attach to the view you are going to animate. In this case, you declared a UISnapBehavior which will initiate a spring-like effect movement to the destination point you declared earlier.

Also, you set the damping property to 20 so that you can see the icon moving out with a reasonable slow speed.

//4 : Finally, you attached the snap behavior to the animator object, which in turns has a reference of the icon view.

Note: UISnapBehavior is one of the UIDynamicBehavior subclasses. Many classes inherits from UIDynamicBehavior, like UIAttachmentBehavior, UICollisionBehavior and UIDynamicItemBehavior (which you will work with in a minute).

So far so good, run the project and click on the button to watch the icon animating and moving out of the screen!

Ok, let’s finish up by implementing another animation for the button. In the same method, below the code you implemented above, place the following implementation:

let btnDestinationPoint: CGPoint = CGPoint(x: 20, y: 300)
btnAnimator = UIDynamicAnimator(referenceView: dismissButton)
btnAnimator.removeAllBehaviors()
let dynamicItemBehavior = UIDynamicItemBehavior(items: [dismissButton])
dynamicItemBehavior.addLinearVelocity(btnDestinationPoint, forItem: dismissButton)
btnAnimator.addBehavior(dynamicItemBehavior)

The code above seems to be familiar to you now 🙂

You just defined another destination coordinates as a CGPoint structure for the button, now the button will be translating off the screen from the bottom direction.

The dynamic animator object reference view is the button itself, and the dynamic behavior is of type UIDynamicItemBehavior.

UIDynamicItemBehavior type is the base dynamic animation configuration for items like UIView objects and is very commonly used when assigning a velocity to the item that matches the velocity of the user gesture.

The argument passed when initialising the UIDynamicItemBehavior object is an array that contains all dynamic items to which you want to apply the dynamic behavior (in this case, it’s just the button).

You then added a linear velocity to the button animation while its moving to the new destination point coordinates.

Before you run the project, let’s make the button corners rounded to look better than the default rectangular corners. Copy the following statements inside the viewDidLoad method, just after the super call:

dismissButton.layer.cornerRadius = 20.0
dismissButton.clipsToBounds = true

That’s it, run the project and click the button to watch your work 🙂

As usual, you can download the final project here.

Keep in mind that setting up a basic custom animation with UIKit Dynamics API is mainly done by following two steps: The first is to define a UIDynamicAnimator object and attach the view you want to animate to it. And the second is to define a UIDynamicBehavior object using one of its subclasses and then attaching it to the animator object to apply the animation effects.

Here is the second part of this series 🙂

If you have any question concerning this tutorial, feel free to ask on the relevant forum thread here.

Also, don’t hesitate to join the discussion below for any suggestion or thoughts.

Malek
iOS developer with over than 11 years of extensive experience working on several projects with different sized startups and corporates.