UIKit Dynamics – Part 2 (Collision Detection, Stasis & Avoiding Memory Cycles)

Note, this is part 2 in the UIKit Dynamics tutorials. In part 1 we talked about getting started using UIKit Dynamics. If you’re not familiar with how to animate views using UIDynamicAnimator and how to make use of UIDynamicBehavior subclasses, it’s crucial to take a look first at part 1.
In part 2, we’ll be discussing 3 more topics related to UIKit Dynamics.

  1. Collision detection; how to detect collisions between the different animated views and boundaries.
  2. Stasis; we’ll get to know what’s meant by stasis and how to detect it.
  3. How to avoid memory cycles in your animation code.

collision_cover

Collision Detection

In some cases, after animating your views, you may want to detect the collision between:

  1. The different animated views (or a subset of them).
  2. The different animated views and the surrounding boundaries.

To be able to detect collisions, you should:

  1. Conform to the UICollisionBehaviorDelegate protocol.
  2. Implement one or more of the functions:
    1. beganContactForItem, withItem
    2. endedContactForItem, withItem
    3. beganContactForItem, withBoundary
    4. endedContactForItem, withBoundary
  3. Set the view controller as the collisionDelegate for your collision behavior.

Let’s add this functionality to our demo app, assume we want to display a message only when our moving squares hit the middle black view at the middle of the screen.
Here’s what our code will look like:

And here’s what it looks like during animation, note the message that appears after collision:

UIDynamics_collision

Stasis

Stasis is the name of the state in which all views are not animating anymore. All the behaviors inside the animator have nothing to do with the views, the universe has stopped moving!

Just like the UICollisionBehaviorDelegate, your view controller can conform to UIDynamicAnimatorDelegate which can tell you 2 things:

  1. When did the UIDynamicBehavior start animating views
  2. When did it end animating views (stasis).

Let’s refactor our code accordingly to display a message when we reach stasis.

As you can see, after the 2 squares stop animating, the stasis message will appear:

UIDynamics_stasis

Avoiding Memory Cycles

When you pay more attention to the code that creates a new push behavior that poses an instantaneous push to shoot squares from right and left:

You’ll notice that push behavior’s action property is referencing the push behavior itself. Well, this is bad, as it results in a memory cycle that will live in the memory forever.
The solution is so simple, you just tell that the action’s closure doesn’t own the push behavior. How is that?

The pushBehavior inside the closure is unowned, meaning; don’t capture it and keep it in memory! I promise you Mr. Closure that it’ll be there when you want to use it.

Full Demo App

The demo app is available on Github, feel free clone, try & customize it.

https://github.com/ahmed-abdurrahman/UIDynamicsDemo

Comments, notes & questions

That’s the end to our 2 part tutorial (part 1 link), hope you found it useful. It’s really my pleasure to answer your questions and receive your notes in the comments section below.

See you next time, stay safe, away from collisions ;]

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s