UIGestureRecognizer Tutorial: Getting Started
In this tutorial, you’ll learn how to configure UIGestureRecognizer objects and how to create custom recognizers in code. By Ryan Ackermann.
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Contents
UIGestureRecognizer Tutorial: Getting Started
25 mins
- Getting Started
- UIGestureRecognizer Overview
- Using the UIPanGestureRecognizer
- Implementing the Panning Gesture
- Connecting the Panning Gesture to the Recognizer
- Letting the Image Views Accept Touches
- Adding Deceleration to the Images
- Easing Out Your Animations
- Pinch and Rotation Gestures
- Implementing the Pinch and Rotation Gestures
- Simultaneous Gesture Recognizers
- Allowing Two Gestures to Happen at Once
- Programmatic UIGestureRecognizers
- Setting UIGestureRecognizer Dependencies
- Creating Custom UIGestureRecognizers
- “Tickling” the Monkey
- Managing the Gesture’s State
- Implementing Your Custom Recognizer
- Where to Go From Here?
Managing the Gesture’s State
One of the things that you’ll change is the state of the gesture. When a tickle completes, you’ll change the state
of the gesture to ended
.
Switch to TickleGestureRecognizer.swift and add the following methods to the class:
override func reset() {
tickleCount = 0
latestDirection = .unknown
tickleStartLocation = .zero
if state == .possible {
state = .failed
}
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent) {
guard let touch = touches.first else {
return
}
tickleStartLocation = touch.location(in: view)
}
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent) {
guard let touch = touches.first else {
return
}
let tickleLocation = touch.location(in: view)
let horizontalDifference = tickleLocation.x - tickleStartLocation.x
if abs(horizontalDifference) < distanceForTickleGesture {
return
}
let direction: TickleDirection
if horizontalDifference < 0 {
direction = .left
} else {
direction = .right
}
if latestDirection == .unknown ||
(latestDirection == .left && direction == .right) ||
(latestDirection == .right && direction == .left) {
tickleStartLocation = tickleLocation
latestDirection = direction
tickleCount += 1
if state == .possible && tickleCount > requiredTickles {
state = .ended
}
}
}
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent) {
reset()
}
override func touchesCancelled(_ touches: Set<UITouch>, with event: UIEvent) {
reset()
}
There’s a lot of code here and you don’t need to know the specifics for this tutorial.
To give you a general idea of how it works, you’re overriding the UIGestureRecognizer
‘s reset()
, touchesBegan(_:with:)
, touchesMoved(_:with:)
, touchesEnded(_:with:)
and touchesCancelled(_:with:)
methods. And you’re writing custom code to look at the touches and detect the gesture.
Once you’ve found the gesture, you’ll want to send updates to the callback method. You do this by changing the state
property of the gesture recognizer.
Once the gesture begins, you’ll usually set the state to .began
. After that, you’ll send any updates with .changed
and finalize it with .ended
.
For this simple gesture recognizer, once the user has tickled the object, that’s it. You’ll just mark it as .ended
.
OK, now to use this new recognizer!
Implementing Your Custom Recognizer
Open ViewController.swift and make the following changes.
Add the following code to the top of the class, right after chompPlayer
:
private var laughPlayer: AVAudioPlayer?
In viewDidLoad()
, add the gesture recognizer to the image view by replacing the TODO:
let tickleGesture = TickleGestureRecognizer(
target: self,
action: #selector(handleTickle)
)
tickleGesture.delegate = self
imageView.addGestureRecognizer(tickleGesture)
At end of viewDidLoad()
add:
laughPlayer = createPlayer(from: "laugh")
Finally, create a new method at the end of the class to handle your tickle gesture:
@objc func handleTickle(_ gesture: TickleGestureRecognizer) {
laughPlayer?.play()
}
Using this custom gesture recognizer is as simple as using the built-in ones!
Build and run. “Hehe, that tickles!”
Where to Go From Here?
Download the completed version of the project using the Download Materials button at the top or bottom of this tutorial.
Congrats, you’re now a master of gesture recognizers — both built-in and custom ones! Touch interaction is such an important part of iOS devices and UIGestureRecognizer
is the key to adding easy-to-use gestures beyond simple button taps.
I hope you enjoyed this tutorial! If you have any questions or comments, please join the discussion below.