Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Gesture recognition with UIWebView

I have set up some gesture recognition in an app that I'm building. One of the gestures is a single finger single tap, which hides the toolbar at the top of the screen. Works great except for one thing: a tap on a link causes the toolbar to go away, too.

Is it possible to detect a tap that was not a tap on a link? Could I do this by seeing where the tap occurred, and only take action if it didn't occur on an html link? Is this is possible, a pointer to how to determine if a link was tapped would be helpful.

Per Octys suggestion, I did attempt to wrap the UIWebView inside a UIView. I'm using interface builder, so I inserted a view in the hierarchy, and made the UIWebView a "child" of the new UIView. The hierarchy looks like this now:

Hierarchy screen shot

I added an IBOutlet for the view in my view controller, and linked it up in interface builder.

I changed the gesture recognizer setup to look like this:

UITapGestureRecognizer* singleTap=[[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(handleSingleTap:)];
singleTap.numberOfTouchesRequired=1;
singleTap.delegate=self;
[self.UIWebViewContainer addGestureRecognizer:singleTap];
[singleTap release];

This code resides in viewDidLoad.

As before, the code correctly sees a single finger single tap, but a tap on a link in the UIWebView also causes the toolbar to go away. I only want the toolbar to go away if a link was NOT tapped.

Anyone have any suggestions?

Thank you.

Chris

Thanks Chris

like image 893
Chris Avatar asked Jun 16 '11 19:06

Chris


3 Answers

Try wrapping your UIWebView in a UIView container and set your gesture recognizers on the container view. Touch events that are not handled by the UIWebView will be passed up the view hierarchy and be intercepted by your container view, assuming it implements the appropriate handlers (and it is these handlers that should implement the code for hiding the toolbars...).

like image 189
octy Avatar answered Nov 03 '22 04:11

octy


OK, so one "hack-ish" workaround is to make the view controller which houses the UIWebView a delegate of the gesture recognizer that you instantiate(UIGestureRecognizerDelegate) I am usually not a fan of solutions like this one, but...

Assign the gesture recognizer to the view that wraps you web view, and set it's delegate to self.

then in the delegate method gestureRecognizer:shouldRecieveTouch method, set the state to indicate the there was a tap event,

Return NO from the delegate method so the event propagates down the responder chain to the UIWebView.

-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch{

    _userTapped = YES;
    [self performSelectorOnMainThread:@selector(hideMenuIfNotLink) afterDelay:??.?];
//??.?? amount of time to lapse to see if shouldStartLoadWithRequest gets called.
   return NO;

}

-(void)hideMenuIfNotLink{
    if(_userTapped)
         //hideMenu
}

Now, in your UIWebViewDelegate shouldStartLoadWithRequest (which gets called when a user has in fact clicked a link)

if(_userTapped){
    _userTapped = NO;
     //possibly code to reshow or verify keep showing menu
}
like image 34
MAX308 Avatar answered Nov 03 '22 05:11

MAX308


You can use the UIWebViewDelegate protocol's -webView:​shouldStartLoadWithRequest:​navigationType: method.

If the navigationType is UIWebViewNavigationTypeLinkClicked, you can get the URL for the click by checking [request URL].

like image 1
Alexsander Akers Avatar answered Nov 03 '22 04:11

Alexsander Akers