Подтвердить что ты не робот

UIWebView shouldStartLoadWithRequest только один раз?

В моем приложении iPhone у меня есть UIWebView, где я загружаю локальный html. Все работает очень хорошо, но теперь я хочу иметь возможность обрабатывать локальные ссылки (в сносках): когда я нажимаю на локальную ссылку, я хочу иметь возможность перейти к сноске, на которую она ссылается, а затем вернуться,

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

Я обработал это, добавив свой код в shouldStartLoadWithRequest и перехватив клики по локальной ссылке; при щелчке по локальной ссылке я работаю над своей магией (скрыть некоторые элементы ui, добавить кнопку "Назад" и т.д.); нажатие на кнопку "Назад" возвращает меня обратно в исходное местоположение в документе html.

Проблема заключается в том, что нажатие ONCE AGAIN по ссылке больше не вызывает shouldStartLoadWithRequest. I.e., следующий код:

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

отображает только "foo bar" ONCE (фактически, дважды - первый раз, когда я первоначально загружаю документ), но только спустя один раз, независимо от того, сколько раз я нажимаю на локальную ссылку

Итак, если у кого-то нет лучшего объяснения, я предполагаю, что UIWebView кэширует документ или ссылку или что-то еще и больше не вызывает обработчик после первоначального вызова; Если это так, как я могу очистить этот внутренний кеш? (без перезагрузки документа)

4b9b3361

Ответ 1

Единственное решение, которое я нашел для этой проблемы, это строка-замените все якоря из "#anchor" - то, что считается URL-адресом, например "| anchor". Таким образом, UIWebView будет считать это реальной ссылкой и попытаться выполнить запрос при нажатии. Это решение, очевидно, будет работать только в том случае, если вы сами обрабатываете все клики и, следовательно, можете интерпретировать измененные привязки. Я могу понять причину поведения UIWebView, но это довольно неприятно. Делегату действительно нужны сообщения для соответствия обработчикам onclick и т.д.

Ответ 2

Я могу обойти это, установив window.location на фиктивный якорь после обработки действительного.

- (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;
    }
}

Ответ 3

Один трюк, который я нашел, когда я столкнулся с этой проблемой, используя встроенные изменения в jQuery, состоял в том, чтобы добавить случайное число в хэш. Таким образом, iOS, кажется, считает это новым запросом:

//set location hash to path
set: function( path ) {
    path += "&" + Math.random();
    location.hash = path;
},

Это должно работать, динамически устанавливая путь через событие onclick.

Ответ 4

Кажется, что это происходит и для меня, когда я использую onclick = "window.location.hash =...; return false;" вместо захвата щелчка.

Если я немного перейду немного или нажму на другой якорь, я снова смогу использовать ссылку.

Ответ 5

Если вы загружаете контент с помощью loadHTMLString, например:

[webView loadHTMLString:htmlString baseURL:[[NSBundle mainBundle] bundleURL]];

Тогда, похоже, достаточно просто перезагрузить html-строку. При нажатии на якорь (снова) вызовите ваш делегат.

Ответ 6

Вариант на бен-Долман (рабочий) код выше. Он "сбрасывает" кеш UIWebView с двумя фиктивными ссылками, чтобы последующие ссылки по-прежнему вызывали метод. Сначала он сохраняет внутреннюю ссылку или фрагмент в NSString с именем savedFragment. Затем он сообщает UIWebview, чтобы загрузить первую фиктивную ссылку #pageX, а затем другую #pageY. Наконец, он захватывает сохраненныйфрагмент и использует его для построения номера страницы, который затем используется в отдельном методе для прокрутки UIWebview до правильного местоположения.

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


   if ([[request URL] fragment]) { //check if fragment exists (treat as internal link)

       NSString *fragment = [[request URL] fragment];

       //If the fragment is neither "pageX" nor "pageY", treat as an internal link in the PDF
       if (![fragment isEqualToString:@"pageX"] &&
           ![fragment isEqualToString:@"pageY"]) {

           savedFragment = fragment; //hold the fragment in savedFragment (NSString)
           [pdfWebView stringByEvaluatingJavaScriptFromString:@"window.location='#pageX'"]; //load UIWebView with first dummy link

       } else if ([fragment isEqualToString:@"pageX"]) {

           [pdfWebView stringByEvaluatingJavaScriptFromString:@"window.location='#pageY'"]; //load UIWebView with second dummy link

       } else {

           NSString *pageString = [savedFragment stringByReplacingOccurrencesOfString:@"page" withString:@""]; //grab the page from savedFragment
           int page = [pageString intValue];
           [self scrollWebViewToPage:page-1]; //scroll to page (seperate method)
       }

       return NO; //do not load any of the dummy links

   } else {

       return YES; //first load of PDF into UIWebView should be allowed
   }

}

Ответ 7

Попробуйте "прикоснуться" к тегу привязки (назначьте его самому). Моя гипотеза заключается в том, что это приведет к обновлению DOM, что снова проверит связь. Не проверял это, это просто идея!

Ответ 8

NSURLRequest * request = [NSURLRequest requestWithURL: fileURL cachePolocy: NSURLRequestReloadIgnoringLocalCacheData timeoutInterval: 60.0];

[webView loadRequest: request];