I'm displaying a document in a UIWebView. I want to place a hotspot over the document to trigger an action when it is tapped, but I also want to maintain the default UIWebView behavior of auto-zooming the document when it is double-tapped. I can't figure out how to respond to the single-taps while letting the UIWebView respond to the double-taps.
I first set up the hotspot as a transparent UIButton with an action, but double-tapping the hotspot resulted in the hotspot action being called twice. So I removed the action from the button and attached a single-tap gesture instead:
UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(singleTapAction:)];
singleTap.numberOfTapsRequired = 1;
singleTap.delegate = self;
[self.hotspot addGestureRecognizer:singleTap];
[singleTap release];
This works the same as the normal button action. But then I created a double-tap gesture, and configured it to block the single-tap gesture with requireGestureRecognizerToFail:
UITapGestureRecognizer *doubleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(zoomWebView:)];
doubleTap.numberOfTapsRequired = 2;
doubleTap.delegate = self;
[self.hotspot addGestureRecognizer:doubleTap];
[doubleTap release];
UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(singleTapAction:)];
singleTap.numberOfTapsRequired = 1;
[singleTap requireGestureRecognizerToFail:doubleTap];
singleTap.delegate = self;
[self.hotspot addGestureRecognizer:singleTap];
[singleTap release];
- (void)zoomWebView:(UITapGestureRecognizer *)gesture {
NSLog(@"double tap");
}
With this setup, a single-tap on the hotspot calls singleTapAction and a double-tap on the hotspot calls zoomWebView (a custom method). This is good because singleTapAction is no longer called twice, but bad because the UIWebView no longer responds to the double-tap.
I tried forwarding the double-tap event from my doubleTap gesture to the UIWebView by subclassing UITapGestureRecognizer, overriding the touchesBegan and touchesEnded methods, and sending their arguments on to the corresponding methods of the UIWebView. When I did that, I could see that my subclass was receiving the events, but the UIWebView didn't respond to the forwarded events. This is to be expected because the Event Handling Guide for iOS says that we can only forward events to custom subclasses of UIView, not to UIKit framework objects.
Is there a way to prevent my single-tap gesture from responding to double-taps that doesn't divert the double-tap events? This seems like a basic requirement, but I can't see a straightforward way to do it. I read about and experimented with UIGestureRecognizer's touch delivery properties, but no combination of values stopped the single-tap gesture from consuming the double-tap gesture.
By the way, the relationship between the hotspot and the UIWebView in my view hierarchy is that of "cousins" -- they are subviews of two sibling views. If I add the gesture recognizers to hotspot view, the web view or their "grandparent" view, I get the same results.