2

A UIWebView is normally focused on the selected content when I double tap a part of a website, and now I want the UIWebView to ignore the double tap but still be able to be interacted with.

How would I go about this?

coder
  • 10,460
  • 17
  • 72
  • 125
Jelmerde
  • 73
  • 1
  • 5

3 Answers3

13

The Double Tap is recognized by a UITapGestureRecognizer. Go through the view hierarchy if you really want this. A little bit tricky, but it should work.

The codes look like this:

- (void)goThroughSubViewFrom:(UIView *)view {
    for (UIView *v in [view subviews])
    {
        if (v != view)
        {
            [self goThroughSubViewFrom:v];
        }
    }
    for (UIGestureRecognizer *reco in [view gestureRecognizers])
    {
        if ([reco isKindOfClass:[UITapGestureRecognizer class]])
        {
            if ([(UITapGestureRecognizer *)reco numberOfTapsRequired] == 2)
            {
                [view removeGestureRecognizer:reco];
            }
        }
    }
}

I've put a demo here: NoDoubleTapWebView

Hope it helps.

mr.pppoe
  • 3,945
  • 1
  • 19
  • 23
3

iOS 5.0+:

A UIWebView contains a UIScrollView to display its content and is accessible by the scrollView property of UIWebView. So, one possible way of doing this is to subclass UIScrollView and override -touchesShouldBegin:withEvent:inContentView. You can get the number of taps from a UITouch object from its tapCount property, which can be used to filter out double-tap gestures and call the super method otherwise. This would look something like:

-(BOOL)touchesShouldBegin:(NSSet *)touches withEvent:(UIEvent *)event inContentView:(UIView *)view {
    UITouch * touch = [touches anyObject];    //Get a touch object
    if (2 == touch.tapCount) {    //If this is a double-tap...
        return NO;                //...don't begin touches
    }
    else {    //Otherwise, call the superclass' implementation
        return YES;
    }
}

However, in order to set the web view's scroll view as your custom subclass, you may also have to subclass UIWebView (which is generally frowned upon). With that said, it would likely work to subclass UIWebView and redefine the scrollView property. In the interface file:

@interface MyAwesomeWebView : UIWebView {

}

@property (nonatomic, readonly, retain) MyAwesomeScrollView * scrollView;

@end

And in the implementation file:

@implementation

@dynamic scrollView

@end

Still, proceed with caution.

Pre iOS 5.0:

As Alan Moore wrote in the comments, you can add a transparent view on top of the web view, capture all touch events with hit testing, and forward the touch events to the web view unless there's a double tap.

EDIT: Updated answer to include caveats about subclassing UIWebView, etc. EDIT 2: Included second answer for pre iOS 5.0

Sean
  • 5,810
  • 2
  • 33
  • 41
  • The UIWebView is not receiving the touchesBegan, could there be any explanation for that? – Thizzer Nov 21 '11 at 14:27
  • Ah yup, I see that now. Looks like the touch events get handled by the scroll view that the web view contains. Updated the answer to match this. – Sean Nov 21 '11 at 14:53
  • There is no 'scrollView' selector pre-iOS5 so this doesn't work on e.g. 4.3 – Thizzer Nov 21 '11 at 15:19
  • Yup, that's probably true. This will work only on iOS 5.0 and later. – Sean Nov 21 '11 at 15:33
  • Go with Alan Moore's second response. Add a transparent view over the webview, capture touch events with hit testing, then forward the events if not a double-tap. This can be tricky and get complicated quickly. I figured since you hadn't accepted that response that you didn't want it in the first place. – Sean Nov 21 '11 at 15:49
  • We'll I was trying to avoid extra views on top of the webview just for filtering out touches. – Thizzer Nov 22 '11 at 09:20
  • The fact of the matter is that you're trying to do something that Apple doesn't really want you to do. Therefore, you're either going to have to do something against their recommendations (like subclassing `UIWebView`) or find some other workaround. Using hit-testing with a transparent view on top of the web view is a perfectly valid way to go and can work great if implemented carefully and correctly. I updated my answer to include this as well. – Sean Nov 22 '11 at 16:29
0

I think the way to do it is to add a UITapGestureRecognizer on top of your UIWebView, then you can filter double taps as you wish.

You can find sample code/discussion here:

Add a UITapGestureRecognizer to a UIWebView

Community
  • 1
  • 1
Alan Moore
  • 6,525
  • 6
  • 55
  • 68
  • If I add an UITapGestureRecognizer it unfortunately fires both events. It doesn't replace it. – Jelmerde Nov 15 '11 at 15:29
  • Hmm, sorry I must have gotten confused with Android. Have you thought about putting a transparent view on top of the UIWebView and using that to filter out the double taps? – Alan Moore Nov 15 '11 at 16:31