开发者

iphone - TapGesture on UIWebView conflicts with the link clicking

开发者 https://www.devze.com 2023-03-31 09:36 出处:网络
I have a UIWebView loaded html string with url links inside. if I click the url links, an internal home-made browser will launch to open that link.

I have a UIWebView loaded html string with url links inside. if I click the url links, an internal home-made browser will launch to open that link.

I added a UITapGestureRecognizer to the UIWebView so if the user taps anywhere on the UIWebView, the UIWebView wil开发者_开发百科l become larger and open a fuller html string.

I set the - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizerto return YES, so the UITapGesture works on the UIWebView without problem.

but a problem occurs when I click on a link inside the UIWebView. clicking on a link will invoke two operations: one is opening the browser for link and the other is to enlarge the UIWebView.

This conflicting is not what I want.

I want two cases separated, i.e., if a user click a link on the UIWebView, then browser will open for that link; if a user tap on the UIWebView where no url links exist, the UIWebView is enlarged.

How can I solve that by make two actions co-exist but no conflicting?

Thanks


I know this question is old, but I've spent a few hours on Google and Stack Overflow, and I thought it might help someone who comes across this question in the future. Hopefully this is the correct way to solve this problem.

I solved this problem by writing some JavaScript code to determine if a link was clicked. My solution was based on this answer on Stack Overflow. There's a JavaScript function that gets the list of all links in the UIWebView, and their boundaries using getBoundingClientRect(). Then the function CGRectContainsPoint() tells us if the given UITouch object is within the links bounding rectangles.

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

    BOOL retVal = YES;

    //Check if a link was clicked
    NSString *js = @"function f(){ var a = document.getElementsByTagName('a'); var retVal = new Array(); for (var idx= 0; idx < a.length; ++idx){ var r = a[idx].getBoundingClientRect(); retVal[idx] = '{{'+r.left+','+r.top+'},{'+r.width+','+r.height+'}}'; } return retVal.join(';'); } f();";
    NSString *result = [self.webView stringByEvaluatingJavaScriptFromString:js];

    NSArray *linkArray = [result componentsSeparatedByString:@";"];
    CGPoint touchPoint = [touch locationInView:self.webView];
    for ( NSString *linkRectStr in linkArray ) {
        CGRect rect = CGRectFromString(linkRectStr);
        if ( CGRectContainsPoint( rect, touchPoint ) ) {
            NSLog(@"Link Clicked");
            retVal = NO;
            break;
        }
    }

    return retVal;
}

Hopefully using JavaScript in this way doesn't cause too much of a performance hit. Especially when it has to be recalculated every tap.


You can implement your UIWebView's delegate's -webView:shouldStartLoadWithRequest:navigationType method. Return NO when you don't want the link to open.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号