I have a bunch of UIButton
s within a UIView
within a UIScrollView
. I'm trying to add a tap recognizer to the scroll view. The tap recognizer fires, but now none of my buttons work.
I know that in iOS5, UIScrollView
can somehow pass a touch event down to the control hierarchy after being done with it. Anyone can help me figure out how to do this?
Set the UIGestureRecognizer
property cancelsTouchesInView
to NO.
UITapGestureRecognizer *singleTapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self
action:@selector(singleTap:)];
singleTapGestureRecognizer.numberOfTapsRequired = 1;
singleTapGestureRecognizer.enabled = YES;
singleTapGestureRecognizer.cancelsTouchesInView = NO;
[tapableView addGestureRecognizer:singleTapGestureRecognizer];
[singleTapGestureRecognizer release];
From UIGestureRecognizer Class Reference
A Boolean value affecting whether touches are
delivered to a view when a gesture is recognized.
When this property is YES (the default) and the
receiver recognizes its gesture, the touches of that gesture that are
pending are not delivered to the view and previously delivered touches
are cancelled through a touchesCancelled:withEvent: message sent to
the view. If a gesture recognizer doesn’t recognize its gesture or if
the value of this property is NO, the view receives all touches in the
multi-touch sequence.
For me a combo of the above answers worked
UITapGestureRecognizer *tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(userDidTap:)];
tapRecognizer.cancelsTouchesInView = YES;
tapRecognizer.delegate = self;
[tapRecognizer requireGestureRecognizersToFail:self.scrollView.gestureRecognizers];
[self.view addGestureRecognizer:tapRecognizer];
-
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
{
if ([touch.view.superview isKindOfClass:[UIButton class]] || [touch.view isKindOfClass:[UIButton class]])
{
return NO;
}
return YES;
}
You could also use the gestureRecognizer:shouldReceiveTouch:
method of the UIGestureRecognizerDelegate
, which is documented here, to accomplish the same thing. It offers a little more flexibility, for instance, if you want to cancel certain touches, but not others. Here's an example,
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
{
if ([touch.view.superview isKindOfClass:[UIButton class]]) return NO;
return YES;
}