How to Add a Gesture Recognizer to Your iOS App

By Jesse Feiler

If you want to truly understand the iOS user experience and how it relates to your app, you need to understand the importance of gestures. UIKit includes gesture recognizers that you can use in your app. You’ll use UIKit to add a gesture recognizer to the Main view so that the user can swipe to the left to make the Test Drive view appear.

Adding the gesture recognizer is easy for both the iPhone and iPad. In MasterViewControlle.m, add the bolded code to viewDidLoad.

- (void)viewDidLoad
{
 [super viewDidLoad];
 AppDelegate* appDelegate =
   [[UIApplication sharedApplication] delegate];
 self.title = appDelegate.trip.destinationName;
 UIImageView* imageView = [[UIImageView alloc]
  initWithImage:[appDelegate.trip destinationImage]];
 self.tableView.backgroundView = imageView;
_detailViewController = (DetailViewController *)
 [[self.splitViewController.viewControllers
 lastObject] topViewController];
 UISwipeGestureRecognizer *swipeGesture =
 [[UISwipeGestureRecognizer alloc] initWithTarget:self
     action:@selector(handleSwipeGesture:)];
 swipeGesture.direction = 
     UISwipeGestureRecognizerDirectionLeft;

UISwipeGestureRecognizer is a subclass of UIGestureRecognizer— the abstract base class for concrete gesture-recognizer classes. The gesture recognizer does the hard work of recognizing a specific gesture and then sends an action message (that you specify) to the target (that you also specify) to go ahead and do something.

In addition to UISwipeGestureRecognizer, you have gesture recognizers for

  • Tap: UITapGestureRecognizer

  • Pinch: UIPinchGestureRecognizer

  • Rotate: UIRotationGestureRecognizer

  • Pan: UIPanGestureRecognizer

  • Touch and hold: UILongPressGestureRecognizer

A window delivers touch events to a gesture recognizer before it delivers them to the hit-tested view — the view where it determined the user has touched — attached to the gesture recognizer. (Note that the gesture recognizer is attached to the view and isn’t part of the responder chain.)

Generally, if a gesture recognizer doesn’t recognize its gesture, the touches are passed on to the view. If a gesture recognizer does recognize its gesture, the remaining touches for the view are canceled.

UISwipeGestureRecognizer is a concrete subclass of UIGestureRecognizer that looks for swiping gestures in one or more directions. Because a swipe is a discrete gesture, the action message is sent only once per gesture.

UISsipeGestureRecognizer recognizes a gesture as a swipe when the specified number of touches (numberOfTouchesRequired) have moved mostly in an allowable direction (direction) far enough to be considered a swipe. You can configure the UISwipe GestureRecognizer recognizer for the number of touches (the default is 1) and the direction (the default is right), as follows:

UISwipeGestureRecognizer *swipeGesture = [[UISwipeGestureRecognizer alloc] initWithTarget:self     
action:@selector(handleSwipeGesture:)];

Here, you create a swipe gesture with a target of self and an action of handleSwipeGesture:. This means that when the gesture recognizer determines it is a swipe, it will send the handleSwipeGesture:to the MasterViewController (self in this case).

Next, because you want the user to swipe to the left to make the Test Drive view appear, you set the direction to left from the default right, as follows:

swipeGesture.direction =     UISwipeGestureRecognizerDirectionLeft;

To handle the swipe — in effect program the response you want to come up with when the swipe occurs — add the code to MasterViewController.m.

What you do here is first find the storyboard in the bundle — in iOS (and OS X), a bundle is a directory that appears to be a single file and contains the executable code, resources such as images and sound, and the nib (storyboard) files.

UIStoryboard *storyboard = [UIStoryboard storyboardWithName:       @"Main_iPad" 
   bundle:nil];

Then the code creates TestDriveController. This is the same thing that the storyboard does (in the segue logic) when you tap the Test Drive button:

UIViewController *viewController = [storyboard instantiateViewControllerWithIdentifier:   @"TestDrive"];

Here’s where that identifier is needed. It’s the only way you can find the view controller that you’ve configured in the storyboard.

Next, you tell the Navigation controller to push the View controller onto the stack (note that this method also updates the Navigation bar) and have it slide its view into place. (If the animated parameter is YES, the view is animated into position; otherwise, the view is simply displayed in place.)

[[self navigationController] pushViewController:       viewController animated:YES];

This is what would’ve been done for you in the segue logic generated by the storyboard.

You’ve only installed the Swipe gesture in the Master View controller. When you are in the Test Drive view, you can only go back by using the Back (New York City) button. In designing an interface, consistency and symmetry are good features to strive for. If you swipe into a view, maybe you should swipe out of a view. That’s how you build powerful, intuitive, and easy-to-learn interfaces.