A UIGestureRecognizer Tutorial
Drag and drop
The interaction between user and App is extremely important. This extends from the look and feel of the application right to the touch gestures that make the user’s interactions delightful.
In order to make the application respond to these gestures you will need UIGestureRecognizer, and this tutorial should help you out in doing so.
Difficulty: Beginner | Easy | Normal | Challenging
Prerequisites:
- You can use gestures in a Single View Application, or use Gestures in the Playground to set up this project
Terminology
UIGestureRecogniser: The base class for gesture recognisers, which include tap and pinch recognisers
The end result
This isn’t going to be pretty. You’re going to see some squares moving around an App according to whether the user drags, drops, pinches or rotates. Thomas Was Alone doesn’t have anything on this stuff!
The setup
The setup for this has been done directly in Playgrounds. In practice I’ve already written a tutorial for this, but to get this working I used import PlaygroundSupport
at the top of the playground and set the live view with PlaygroundPage.current.liveView = MyViewController()
. I’ve written the gestures in viewDidLoad()
and kept things tidy by using loadView()
(there is a guide on this HERE
). Don’t worry though, this is really about the gestures and not the setup, and the full Playground is at the bottom of this article.
The theory
The UIGestureRecognizer
class help us detect common gestures like taps, pinches, swipes, pans, long presses and rotations. This avoids having to register touch notifications for each UIView
and then use touchesBegan(_:with:)
for that view. Let us avoid that kerfuffle and get started!
A pan gesture
We set up the pan recogniser in viewDidLoad()
with the following couple of lines to create the gesture recogniser .
The UIPanGestureRecognizer
looks for the panning gesture

which calls the following method to handle the pan:

The sender is passed to the method, and this has a view associated with the sender — which we can then make a translation (which is then set through setTranslation:inView:
). Set translation makes sure that we are working in the correct coordinate system — if not the translation will not work correctly!
Pinch
Option + Shift to pinch is the way to get those two circles on a view to enable to pinch gesture is the way to go there. It can be a little tricky in the Playground, but it does work in the end (if you cannot get it working then perhaps using the full simulator is the way to go).
The UIPinchGestureRecognizer
looks for the pinch gesture

which calls for the following method to handle the pinch:

Wait, *what is scale*?
The distance between fingures on the screen is the scale factor. At the beginning of the gesture, the scale facto is 1.0, and as the distance between the fingers increases the scale factor also increases (or decreases if the distance decreases). When the gesture has finished, the scale factor is set back to 1 as the image is reset to be a standard image with a scale factor as 1 (after each change).
A tap gesture
We might wish to register when the user taps an object on the screen.

Which in this case will print a description of the gesture to the console

To change this gesture to a double tap, simply change the number of taps required using the property tap.numberOfTapsRequired
to 2 (or of course whatever integer representing the number of taps is required).
A long-press gesture
We might wish to register when the user taps an object on the screen for a longer period than the simple tap gesture.
The UILongPressGestureRecognizer
looks for the long press gesture

Which in this case will print a description of the gesture to the console

A rotation gesture
We might wish to rotate our square when a user selects it with two fingers.
The UIRotationGestureRecognizer
looks for this rotation:

Which in this case will rotate the UIView
subclass:

A swipe
I’d say that it makes more sense to apply a swipe gesture to the whole UIViewController
rather than an object.
The UILongPressGestureRecognizer
looks for the long press gesture

Which in this case will print a description of the gesture to the console

If you decide to use a different direction choose a direction to feed to the property swipeLeft.direction
(of course you might want to change the name of the gesture from swipeLeft too!
Multiple views per gesture
Unfortunately this is not possible. Because every gesture can only be attached to one view this is unfortunately rather a fixed rule.
Did you make sure the user can interact?
When you add a gesture to a UIImageView
it is a common issue that isUserInteractionEnabled
is set by default as false. So do this: Make sure isUserInteractionEnabled
is set as true either in the Storyboard or though code.
Conclusion:
Pinches, taps and rotations are great ways for users to interact with iOS applications. Making your code a must for the disconcerting user.
The Repo makes things rather easier to follow in this project, and I do recommend you download this project to walk through the gestures.
This article has walked through pan gestures, tap gestures, long-press gestures and swipe gestures. They are all similar, so I hope this article really has helped you out in developing your own applications.
If you’ve any questions, comments or suggestions please hit me up on Twitter