UIDynamics’s basis with Playground

Andrés Brun
5 min readDec 23, 2016

--

Overview

UIDynamics is a engine created by Apple that modifies center, transform and bounds of instances of classes that conforms to UIDynamicItem protocol based on defined behaviours.

UIView and UICollectionViewLayoutAttributes conforms by default to UIDynamicItem protocol. In this article we are going to focus on UIViews.

The full Playground is available in my Github account here. I totally recommend to download it and play with it to see how every behaviour works. An example of how one of them looks like:

Playground: first we apply a continuous push and then an instant push. Also it uses gravity, collision, elasticity and friction.

Setting Up Playground

Investigating for this article I have discovered that Playground is a really useful tool to implement and polish a UIDynamic behaviour because it is really easy to set up and very fast to get feedback from changes.

To create a Playground with a view to play with:

Opening the assistant editor with Timeline you can see a black view ready to place elements in. So let create our first behaviour: gravity.

Steps are always the same:

  1. Create the animator object with the reference view. Every view we want to include in the behaviour has to be part of its hierarchy.
  2. Create the behaviour, in this case we use UIGravityBehaviour (we will explain it later), and we add it to the animator.
  3. That’s it. From now on those views will fall in the screen as real objects in real word would do.

So these view’s centers are modified by the dynamic engine, thought the animator, following the behaviour we have defined.

UIDynamics effects

Now that we know how to create behaviours and play with them with Playground let’s analyze them one by one.

UIDynamicItemBehavior

It is the base behaviour that allows to set some physics properties like elasticity, friction, density or resistance. To add a ball like physic behaviour for instance:

UIPushBehaviour

It defines a push behaviour over an object either continuously or instantaneously.

For instance if we want a continuous force to push the object to the right (a vehicle accelerating in a 2D game for instance) we should use something like:

A continuous force vector with a magnitude of 1.0, applied to a 100 point x 100 point view whose density value is 1.0, results in view acceleration of 100 points per s². (Apple’s doc)

On the other hand if we would like to simulate a ball shot in a billiard game we should use and instantaneous one. In this case we have to create a new behaviour object every time we want to apply it.

UIGravityBehaviour

It defines an acceleration behaviour that simulates the gravity towards a vector. It is very straightforward to configure it:

UISnapBehaviour

It defines the behaviour that simulates the object is pinned to one point like a magnet. It is very easy to configure:

An example of how UISnapBehaviour works visually when snapPoints changes

UICollisionBehaviour

It simulates the physical collision between elements. There are two types:

  • Between elements: by adding more than one item.
  • Against barriers: by adding a boundary or using the reference view as boundary.

This behaviour also provides a collisionDelegate to inform of contacts between elements or barriers.

By default every collision boundary of the objects involve are rectangular, if we want to play with circular objects (balls of the example above for instance) we need to subclass the view like:

You can also use BezierPaths to define the shape of the object by setting collisionBoundsType to .path and overriding collisionBoundingPath.

UIAttachmentBehaviour

This could be the most complex behaviour of all of them, it simulates a physical attachment between:

  • Two elements. An anchor point for both can be specify.
  • One elements and one point. The anchor point of the element can be specify.

The main methods to achieve these behaviours are:

Let’s see how it works practically in an example:

An example of a normal attachment with `length = 100` and `offsetFromCenter = .zero`

But since iOS 9 Apple added new methods for this behaviour that provides very interesting ways of attaching elements. Let’s take a look of them:

Sliding attachment: This one creates an attachment between two elements in a way the first one can move in an imaginary axis defined by axisOfTranslation related with the second element. Trying to get out from this imaginary line will result in a rotation of the referent element of this axis.

A visual demonstration can help to understand this concept:

The vector is (1, 0) 100px upper to the reference view. So we can move the second view left to right without moving the reference view but up and down will force to move it.

Limit attachment: This behaves like if a rope was tied to both elements, so it will drag the second view when the distance between anchor points is larger than the length parameter. It doesn’t affect to transform or bounds, which means the element doesn’t rotate.

Fixed attachment: It behaves like if a stick was tied to both elements, so relative position between elements doesn’t change.

Pin attachment: It simulates two object nailed together.

Common errors

Those are the most common error I have found in my research, hopefully someone in the same situation can save some time by reading them:

  1. To try to modify the center, bounds or transform manually. For instance adding a gesture to move a view changing its center won’t work. It will have conflicts with UIDynamics engine and it won’t apply physics behaviours. To solve this you can use UIAttachmentBehavior with anchorPoint the position where the user is tapping.
  2. I haven’t had major problems combining UIDynamics + Auto Layout, just one estrange behaviour when I was removing an attachment behaviour and adding a push one. Instead of fluently pushing the view from the same point it was, it reseted the position. The solution was to add the push behaviour before removing the attachment one.

Conclusions

UIDynamics is a great tool that used wisely can add a lot of value to your apps or just get fun playing with it. Combining with Playgrounds makes very easy and fast to model new behaviours.

Apple’s documentation and articles about this subject out there are not very deep so you have to guess some of the parameter ranges. Some of them doesn’t have even formal units like frictionTorque of UIAttachmentBehavior for instance.

To build a more complex behaviour combining some of the basic ones I decided to write another post explaining how to build a modal behaviour inspired in Swarm.

--

--