Recreating Apple’s Rubber Band Effect in Swift

Victor Baro
May 8, 2015 · 3 min read

For the past 6 months we have been working on the most challenging and fun app I have ever developed: Thoughts. This is also the first Produkt’s own app, so we couldn’t be more excited about its imminent launch.

One of the trickiest features we encountered while developing Thoughts was to recreate Apple’s scrolling view capabilities (some of them).

Whilst Panning and Zooming can be defined by using gesture recognizers, combining the two was far more complicated. Zooming into a specific point (e.g. middle of your fingers) involves not only zooming but shifting the content. Nevertheless, my favourite part of all was to replicate the rubber band behaviour.

Thoughts zooming — brief video showing Thoughts enormous zooming and rubber band behaviour

The maths behind it

The Control Centre is a perfect rubber band interaction example.

Image for post
Image for post
Control Center adds rubber band behaviour when it is pulled up

By interacting with the Control Centre behaviour, the first mathematical function that came to my mind was the square root. However… it didn’t feel right, and not as natural as Apple’s. Here is when Swift (and specially playgrounds) became very useful.

Image for post
Image for post
Swift playground for finding the most appropiate mathematical function

After a few tests, the best strategy was to use log10 — it mimics quite closely Apple’s built-in behaviour.

Image for post
Image for post
Logarithmic functions (screenshot from Tydling app)

I tried multiple logarithmic functions, including the neperian, but log10 was the most optimal.

The GIF below illustrates the comparison between square root, log10 and a function involving a power of 4. This last function works very well and, depending on the exponent, the ‘rubber’ effect becomes more/less elastic (that is, the distance gets longer/shorter). However, the downside of using this function is that there is a maximum value you shouldn’t cross (otherwise, the movement gets reversed).

Image for post
Image for post

Using this behaviour in ‘real life’ interactions

Replicating Apple’s scroll view will not be necessary on a standard app; we did it for Thoughts to create its infinite canvas. However, some situations (like the example below) can require a rubber band effect where there is no scroll view involved.

To showcase one of the above functions, I have included the following example in the project.

Image for post
Image for post

The green view is located using Autolayout and has a PanGestureRecognizer attached to it that calls the following method:

Where the last part of it, the logConstraintValueForYPoisition, takes care of applying the rubber band effect after the view exceeds the vertical limit using a log10 function. Tip: I like to use log10 from 1 to X (0.x values grow massively quick).

In this example, animateViewBackToLimit() is implemented using a simple UIView animation block to keep the project simple, however I am not a big fan of them.

Find the project in GitHub

One last word

UIAttachmentBehaviour can also be used in some situations involving rubber band behaviour. This is only another tool to add in your toolbox ☺

PS: this is the first time I have published Swift code. I would really appreciate if you can help me to improve it in any way.

Thoughts on Thoughts

The forward thinking tool for iPhone and iPad

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch

Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore

Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store