zoul zoul - 5 months ago 101
iOS Question

How can I reliably detect a link click in UIWebView?

I have a

and I need to do something when user taps a link. There’s a delegate callback that can be used to detect the taps:

- (BOOL) webView: (UIWebView*) webView
shouldStartLoadWithRequest: (NSURLRequest*) request
navigationType: (UIWebViewNavigationType) navigationType
if (navigationType == UIWebViewNavigationTypeLinkClicked) {


The problem is that this code doesn’t handle all link clicks. As an example, a plain Google Search results page does something weird with the links:

<a href="http://example.com/" class="l" onmousedown="return rwt(…)">
<em>Link Text</em>

function results in the links not triggering the
event when tapped. Is there a way to reliably detect all events that fall into the “navigate to some other page” bucket?


So far I have arrived at the following solution. First, I inject some JS code into the page when loaded:

function reportBackToObjectiveC(string)
    var iframe = document.createElement("iframe");
    iframe.setAttribute("src", "callback://" + string);
    iframe = null;

var links = document.getElementsByTagName("a");
for (var i=0; i<links.length; i++) {
    links[i].addEventListener("click", function() {
    }, true);

When user taps a link, I know it in advance thanks to the webView:shouldStartLoadWithRequest: navigationType: delegate call:

if ([[[request URL] scheme] isEqualToString:@"callback"]) {
    [self setNavigationLeavingCurrentPage:YES];
    return NO;

Then if another request comes and _navigationLeavingCurrentPage is true, I know the user has clicked a link even though the navigation type flag is UIWebViewNavigationTypeOther. I still have to test the solution extensively, for I’m afraid that it will lead to some false positives.