Understanding UIGestureRecognizer

I recently presented a side project I’ve been working on for the past couple of weeks at the “Flatiron Presents” meetup at school. My classmate and I were able to create a pretty cool quote matching game that allows a user to match famous quotes with the celebrity or well-known figure who said it. One of the view controllers allowed a user to use their finger to drag an image of the celebrity to a designated answer area which would trigger a method that determined if they were correct. In order to make this dragging happen I used a class called UIPanGestureRecognizer.

UIPanGestureRecognizer is a sub-class of UIGestureRecognizer. According to Apple documentation, UIGestureRecognizer “decouples the logic for recognizing a gesture and acting on that recognition.” Basically, the class recognizes all of the actions our fingers can do on a mobile screen. Gestures such as panning (or dragging), pinching, swiping, and rotating are all behaviors defined within this class. You can also set the minimum amount of touches or fingers required to complete certain gestures. Here is a list of common sub-classes of UIGestureRecognizer:

  • UITapGestureRecognizer
  • UIPinchGestureRecognizer
  • UIRotationGestureRecognizer
  • UISwipeGestureRecognizer
  • UIPanGestureRecognizer
  • UIScreenEdgePanGestureRecognizer
  • UILongPressGestureRecognizer

Gestures can either be discrete or continuous. Discrete means a gesture “occurs but once in a multi-touch sequence and results in a single action sent.” These gestures typically consist of a tap or double tap gesture. A Continuous gesture “sends an action message for each incremental change until the multi-touch sequence concludes.” These gestures typically have a beginning or ending state and consist of multiple actions to complete as indicated in this sequence:

Possible — → Began — → [Changed] — → Cancelled

Possible — → Began — → [Changed] — → Ended

In order to first initialize a UIPanGestureRecognizer, you should implement the following code:

UIPanGestureRecognizer *panGestureFirstImage = [[UIPanGestureRecognizer alloc] initWithTarget: self action: @selector(dragFirstImage)];
[self.firstImage addGestureRecognizer:panGestureFirstImage]

In order to initialize the gesture, you need to set the target of the gesture. The target represents an object that is the recipient of action messages sent by the receiver when it recognizes a gesture. Also, you need to set the action of the gesture which represents the method that will be called once the gesture begins. The last step is passing the initialized UIPanGestureRecognizer object to the actual object you are applying the gesture to.

Your method for creating a drag gesture might look like this:

-(void)dragFirstImage:(UIPanGestureRecognizer *)gesture
CGPoint fingerLocation = [gesture locationInView:self.view];
if (gesture.state == UIGestureRecognizerStateBegan)
self.oldPosition = fingerLocation;

CGFloat deltaX = fingerLocation.x -self.oldPosition.x;
CGFloat deltaY = fingerLocation.y -self.oldPosition.y;

Now that I have experience using pan gestures, I’d like to use similar sub-classes for creating rotation and pinch gestures. From my research, the setup process is similar! You first have to initialize the gesture and pass it to the object you are applying the gesture to. The last step is creating the actual method itself. I’ll add an example rotation gesture setup below.


Rotation Gesture Initialization Example

UIRotationGestureRecognizer *exampleRotationGesture = [[UIRotationGestureRecognizer alloc] initWithTarget: self action: @selector(rotateFirstImage)];
[self.firstImage addGestureRecognizer:exampleRotationGesture]

Pinch Gesture Initialization Example

UIPinchGestureRecognizer *examplePinchGesture = [[UIPinchGestureRecognizer alloc] initWithTarget: self action: @selector(pinchFirstImage)];
[self.firstImage addGestureRecognizer:examplePinchGesture]

Tap Gesture Initialization Example

UITapGestureRecognizer *exampleTapGesture = [[UITapGestureRecognizer alloc] initWithTarget: self action: @selector(tapFirstImage)];
[self.firstImage addGestureRecognizer:exampleTapGesture]