Dynamic animation is an area of science concerned with the behavior of physical bodies when they are subjected to forces or displacements, and the subsequent effects of those bodies on their environment. In iOS app development, dynamic animation represents simplified physics that is useful for building a prototype model, well-tuned for performance. However, bear in mind that the dynamic animation system is a 2D physics inspired animation system, no real physics are used here! Moreover, bear in mind that the dynamic animations that I will show here are a part of UIKit. Hence, they are intended for UI and not for building video games. If you want to build a video game, you should instead use Sprite Kit, which provides its own physics engine.

To represent a dynamic animation system in UIKit, you need to use several components offered by the API. Starting with iOS 7, Apple introduced UIKitDynamicItem and UIDynamicAnimator. In iOS 9, UIFieldBehavior and UIDynamicItemGroup were introduced to expand and improve the existing classes.

UIDynamicItem represents the physical body subjected to forces and displacements. If you have a group of items that should move together and behave as a single unit, you should use UIDynamicItemGroup. UIFieldBehavior represents the field-based physics applied to dynamic items. This class was introduced in iOS 9 and Apple provides built-in types, like gravity, turbulence and spring, which work as out-of-the-box behaviors. More than one UIFieldBehavior can also be applied at the same time. Behaviors combined together will create more complex region shapes behaving as a combination of all of the behaviors together. Then, UIDynamicAnimator provides physics-related capabilities and animations for its dynamic items, and provides the context for those animations. Before we begin a hands on example in Swift, let’s take a look at the UIKit components, one by one.

UIDynamicItem

A UIDynamicItem instance is an object eligible to participate in UIKit Dynamics. It has properties that allow you to configure physical properties like bounds, center and transform (rotation) and collision.

title

UIDynamicItemGroup

A UIDynamicItemGroup object represents a dynamic item composed by multiple other dynamic items. Creating a group you can manipulate a group of dynamic items together and treat them as a single unit for the purpose of collisions. The attributes of the dynamic item group are derived from the items of the group itself, meaning that the group’s bounds rectangle is the rectangle that encloses all of the contained dynamic items, and the center point of the group is the center point of the bounds rectangle.

title

UIDynamicAnimator

A dynamic animator provides physics-related capabilities and animations for its dynamic items, and provides the context for those animations. It does this by intermediating between the underlying iOS physics engine and dynamic items, via behavior objects that you add to the animator.

You specify dynamic behaviors using any of the iOS primitive dynamic behavior classes: UIAttachmentBehavior, UICollisionBehavior, UIDynamicItemBehavior, UIGravityBehavior, UIPushBehavior, and UISnapBehavior. Each of these behaviors provides configuration options and lets you associate one or more dynamic items to the behavior. To activate a behavior, add it to an animator.

UIFieldBehavior

UIFieldBehavior applies field-based physics to dynamic items. It defines an area in which forces such as gravity, magnetism, drag, velocity, turbulence, and others can be applied. After creating the field behavior type that you need, you can configure the strength of the force along with any other field attributes.
The built-in field types offered are: linear and radial gravity, noise, custom, drag and velocity, vortex, turbulence, spring, electric and magnetic.

Hands-on example

I want to build a dynamic animation system with an object orbiting around a point (the center of the orbit). Brushing up on our physics knowledge, an orbit is the gravitationally curved path of an object around a point in space. The following schema explains the 2 simultaneous forces that I am going to use to make the blue object orbit around the yellow object. Forces are represented by red vectors while the blue object moves counterclockwise along the dotted black path.

title

I am going to create two field behaviors and associate them with the blue object. Due to the type of field I’m using, I’m going to also configure a UIDynamicItemBehavior object for the blue object to define its density. You could also use a UIDynamicBehavior if you want to configure the object as an electron or proton, associating a negative or positive electric charge.

Let’s put all these concepts in practice. Launch Xcode and create a Single View Application project. Name it Dynamics and select Swift as language. Open the ViewController.swift and add an outlet orbitingView of type UIView:

In the Main.storyboard, add a view as a subview of the view of the view controller and connect it to the previously created IBOutlet. Notice that the property observer is used to change the view layer properties and render a blue circle.

In the ViewController.swift, also add the following property to lazily create a dynamic animator:

Let’s also add a property that will hold the center of the view controller’s view.

We need this point as the center of the radial gravity behavior:

In the previous chuck of code, line 1 creates a dynamic behavior that models a radial gravitational force, defining the shape of the field. The gravity force is centered in the view of the view controller. Line 2 defines that the field exerts a force on items that lie inside a region comprised by a circle with a radius of 300 points. Line 3 defines the strength of the field. The default value for this property is 1.0, but I set it to 1.5, because that seems like a good number for what I’m trying to accomplish (I am following the suggestion provided in the documentation). Line 4 defines how quickly the field strength diminishes as the distance from the field’s center increases. The default value for this property is zero, which yields a uniform field that does not diminish over distance. I set this property to 4. Line 5 sets the minimum distance at which to start calculating new values for the field. I set this property to 50.

I create a new dynamic behavior that models a vortex force and I configure the behavior, similarly to the previous one.

Line 6 creates the dynamic behavior that models a vortex force. Line 7 defines the position of the vortex field, centering the fields’s position in the view controller. Then, line 8 configures the region defining the area of influence with a circle radius of 200 points. Line 9 defines the strength of the field. I set it to 0.005.

Then, edit the viewDidAppear(_:) as follows:

In line 10, I enable a property for debugging purposes. This property allows me to visualize the field force strength and direction.

From line 11 to 13, I create a UIDynamicItemBehavior object to change the dynamic item (orbitingView) density.

After creating the field behavior, lines 14 and 15 add the dynamic item to the 2 field behaviors that we previously created. Finally, lines 16 and 17 add the two behaviors to the dynamic animator. Build and run the project and you should see the following.

You could also add more field behaviors acting simultaneously over the same object to produce the following behavior.

Conclusions

I hope you enjoyed this iOS development tutorial on dynamic animation systems. As you learned here, you can prototype 2D physics inspired animation systems. There are many built-in types of dynamic animations that you can use and combine together to create more complex UI animations for your iOS apps.

Keep innovating, swiftly!

Eva

Eva Diaz-Santana (@evdiasan) is cofounder of InvasiveCode. She develops iOS applications and teaches iOS development since 2008. She also worked at Apple as Cocoa Architect and UX designer.

iOS Consulting | INVASIVECODE

iOS Training | INVASIVECODE