UITapGestureRecognizer and UIButton
April 16, 2012, 10:54 p.m.

An issue that I need to look up every time I encounter it, is how to handle UIButtons that are placed on a view that has a UITapGestureRecognizer added to it, so now I decided to document it for my own convenience.

The problem is that the UIControlEventTouchUpInside event of the UIButton conflicts with the UITapGestureRecognizer and so the button action does not get called.

The solution is straightforward, and is just a matter of implementing the UIGestureRecognizerDelegate method gestureRecognizer:shouldReceiveTouch: and only return YES when the UITouch object's view property is not of class UIButton.

First we create the UITapGestureRecognizer and add it to our view.

// Create tap recognizer
UITapGestureRecognizer *tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(resignFirstResponders:)];

// Add recognizer to view
[self.scrollView addGestureRecognizer:tapRecognizer];

// Set delegate to self
// Remember that self must conform to the UIGestureRecognizerDelegate protocol
tapRecognizer.delegate = self;

Then we implement the delegate method.

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
    return ![touch.view isKindOfClass:[UIButton class]];

Easy! And now also easy for me to look up.