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

UIWebView - Как определить последнее сообщение webViewDidFinishLoad?

Сообщение webViewDidFinishLoad, кажется, отправляется каждый раз, когда объект any загружен на страницу. Есть ли способ определить, что выполняется вся загрузка контента?

4b9b3361

Ответ 1

Интересно, я бы не подумал, что это сработает. Хотя я уверен, что есть другие способы сделать это (есть способ извлечь URL из сообщения webViewDidFinishLoad, чтобы вы могли видеть, какая из них является главной страницей, заканчивающей загрузку?), Главное, о чем я могу думать, это использовать оцененныйProgress, чтобы проверить ход страницы и отпустить все, что вы хотите сделать, когда она закончит загрузку на 100%, что я и делаю в своем приложении. Google "iphone webview оценкампрогресс" и нажмите на первую ссылку для руководства, которое я написал о том, как это сделать.

Update:

Пожалуйста, используйте вместо меня мой ответ на phopkins! Использование частных API в ваших приложениях - плохая идея, и вы, вероятно, получите отказ, и его решение будет правильным.

Ответ 2

Я предполагаю, что iframe вызывает пару webViewDidStartLoad/webViewDidFinishLoad.

Проверка [webView isLoading], упомянутая в качестве ответа, не работала для меня; он возвратил false даже после первого из двух вызовов webViewDidFinishLoad. Вместо этого я отслеживаю загрузку следующим образом:

- (void)webViewDidStartLoad:(UIWebView *)webView {
  webViewLoads_++;
}


- (void)webViewDidFinishLoad:(UIWebView *)webView {
  webViewLoads_--;

  if (webViewLoads_ > 0) {
    return;
  }

  …
}

- (void)webView:(UIWebView*)webView didFailLoadWithError:(NSError*)error {
  webViewLoads_--;
}

(Обратите внимание, что это будет работать только в том случае, если стартовые/готовые пары не появятся серийно, но по моему опыту до сих пор этого не произошло.)

Ответ 3

Проверьте это, это определенно сработает для вас:

- (void)webViewDidFinishLoad:(UIWebView *)webView {
    if ([[webView stringByEvaluatingJavaScriptFromString:@"document.readyState"] isEqualToString:@"complete"]) {
        // UIWebView object has fully loaded.
    }
}

Ответ 4

Другим способом отслеживания прогресса загрузки с меньшим контролем является наблюдение за уведомлениями WebViewProgressEstimateChangedNotification, WebViewProgressFinishedNotification и WebViewProgressStartedNotification. Например, вы можете наблюдать за этими уведомлениями, чтобы реализовать простой индикатор прогресса в своем приложении. Вы обновляете индикатор прогресса, вызывая метод оценочногоProgress, чтобы получить оценку количества загружаемого содержимого.

из http://developer.apple.com/library/mac/#documentation/Cocoa/Reference/WebKit/Classes/WebView_Class/Reference/Reference.html

Ответ 5

Вы также можете использовать эту короткую категорию I, которая добавляет блоки в UIWebView, а также позволяет выбирать между поведением по умолчанию UIWebView (получение уведомления после каждой загрузки объекта) или "ожидаемое" поведение (получение уведомлений только при полной загрузке страницы) загружен).

https://github.com/freak4pc/UIWebView-Blocks

Ответ 6

Мне нужно было захватить переменную со страницы, которая еще не была полностью загружена.

Это сработало для меня:

- (void) webViewDidFinishLoad:(UIWebView *)webView {
    NSString *valueID = [webView stringByEvaluatingJavaScriptFromString:@"document.valueID;"];

    if([valueID isEqualToString:@""]){
        [webView reload];
        return;
    }

    //page loaded
}

Ответ 7

Все варианты действительно не работали для моего варианта использования. Я использовал пример phopkins, слегка модифицированный. Я обнаружил, что если HTML, загруженный в веб-просмотр, содержал изображение, которое было бы отдельным запросом, который происходил последовательно, поэтому мы должны учитывать это, и я сделал это с помощью таймера. Не лучшее решение, но, похоже, оно работает.:

- (void)webViewActuallyFinished {
     _webViewLoads--;

    if (_webViewLoads > 0) {
        return;
    }

    //Actually done loading

}

- (void)webViewDidStartLoad:(UIWebView *)webView {
    _webViewLoads++;
}


- (void)webViewDidFinishLoad:(UIWebView *)webView {


    [NSTimer scheduledTimerWithTimeInterval:2 target:self selector:@selector(webViewActuallyFinished) userInfo:nil repeats:NO];
}

- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error {
  _webViewLoads--;
}

Ответ 8

Привет, может быть, уже немного назад, но я надеюсь, что это поможет.

Я просто использовал уведомление, когда он вводит метод webViewDidFinishLoad, чтобы я мог захватить один экземпляр метода, а затем я обнаружу уведомление и сделаю свою логику оттуда.

надеюсь, что это поможет. он не захватывает последний вызываемый экземпляр метода webViewDidFinishLoad, но позволяет вам что-то делать, когда он был вызван, а не повторять вызовы этого конкретного метода (например, показывая кнопку) тоже.

********* ИЗМЕНИТЬ *********

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

В качестве альтернативы, я думаю, вы можете сделать счетчик по методу делегирования webViewDidStartLoad, а также по webViewDidFinishLoad, чтобы убедиться, что они одинаковы до того, как вы запустите свои коды. это, однако, является уродливым взломом, поскольку мы никогда не узнаем, сколько раз он будет вызван, если только я не загружаю html-канал и вы можете добавить JavaScript, чтобы проверить, сколько элементов на странице, которую вы загружаете. Я просто использую некоторые из методов, которые я пытался решить. надеюсь, что это поможет.

приветствуется обратная связь. спасибо!

Ответ 9

Здесь я использую, чтобы показать spinner, когда DOM загружается, построенный поверх ответа @Vinod.

Обратите внимание, что между webViewDidStartLoad и webViewDidFinishLoad готовое состояние завершено из предыдущего запроса (если есть), то почему опрос должен начинаться после webViewDidFinishLoad.

Возможные значения readyState: загрузка, интерактивность или завершение (и, возможно, nil?)

- (void)webViewDidStartLoad:(UIWebView *)webView {
    [self spinnerOn];
}

- (void)webViewDidFinishLoad:(UIWebView *)webView {
    [self startDOMCompletionPolling];
}

- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error {
    [self startDOMCompletionPolling];
}


- (void)startDOMCompletionPolling {
    if (self.domCompletionListener) {
        [self.domCompletionListener invalidate];
    }
    self.domCompletionListener = [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(checkDOMCompletion) userInfo:nil repeats:YES];
}

- (void)checkDOMCompletion {
    NSString *readyState = [self.webView stringByEvaluatingJavaScriptFromString:@"document.readyState"];

    if (readyState != nil) {
        if (readyState.length > 0) {
            if ([readyState isEqualToString:@"loading"]) { //keep polling
                return;
            }
        }
    }
    //'completed', 'interactive', nil, others -> hide spinner
    [self.domCompletionListener invalidate];
    [self spinnerOff];
}

Ответ 10

Как я это делаю:

- (void)webViewDidFinishLoad:(UIWebView *)webview  {
    if (webview.loading)
    return;
    // now really done loading code goes next
    [logic]
}