Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UIWebView shouldStartLoadWithRequest only called once?

In my iPhone app, I have a UIWebView where I'm loading a local html. Everything works up just fine, but now I want to be able to handle local links (to footnotes): when I click on a local link, I want to be able to jump to the footnote refered by it, then be able to come back.

<a href="#tofootnote">jump to footnote</a>

I handled this by adding my code to shouldStartLoadWithRequest and intercepting local link clicks; when a local link is clicked, I work my magic (hide some ui elements, add a back button, etc..); clicking on the back button jumps me back to the original location in the html document.

The problem is that clicking ONCE AGAIN on the link no longer calls shouldStartLoadWithRequest. I.e., the following code:

- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
 NSLog(@"foo bar");
 return YES;
}

only displays "foo bar" ONCE (actually, twice - the first time when I'm initially loading the document), but only ONCE afterwards, regardless of how many times I'm clicking on the local link

So, unless anyone has a better explanation, I'm guessing that the UIWebView caches the doc or link or something and no longer calls the handler after the initial call; If this is the case, how can I clear this internal cache up? (without reloading the document)

like image 683
Alex Avatar asked Dec 03 '09 14:12

Alex


2 Answers

The only solution I've found for this problem is to string-replace all the anchors from "#anchor" to something that is considered a URL, like "|anchor". This way UIWebView will think it's a real link and attempt the request when clicked. This solution obviously will only work if you are handling all the clicks yourself and hence can interpret the changed anchors. I can understand the reason for the behavior of UIWebView, but it is rather frustrating. The delegate really needs messages to match the onclick, etc. handlers.

like image 103
GrafikRobot Avatar answered Sep 22 '22 08:09

GrafikRobot


I'm able to workaround this by setting window.location to a dummy anchor after handling the valid one.

- (BOOL)webView:(UIWebView *)aWebView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
    if ([[request URL] fragment]) {
        if ([[[request URL] fragment] isEqualToString:@"__DUMMY_ANCHOR"])
            return NO;

        // Do your custom handling of the anchor here

        // Change the location to a non-existent anchor
        [aWebView stringByEvaluatingJavaScriptFromString:@"window.location='#__DUMMY_ANCHOR'"];

        return NO;
    }
}
like image 24
Ben Dolman Avatar answered Sep 19 '22 08:09

Ben Dolman