iphone - это - webview swift 4




UIWebView: когда страница действительно заканчивала загрузку? (7)

Мне нужно знать, когда веб-страница полностью загружена UIWebView. Я имею в виду, действительно, полностью, когда все переадресации завершены, и динамически загруженный контент готов. Я попытался вставить javascript (запрос для document.readyState == 'complete' ), но это не кажется очень надежным.

Может быть, событие из частного api, которое принесет мне результат?


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

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

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


Вот упрощенная версия ответа @jasonjwwilliams.

#define JAVASCRIPT_TEST_VARIBLE @"window.IOSVariable"
#define JAVASCRIPT_TEST_FUNCTION @"IOSFunction"
#define LOAD_COMPLETED @"loaded"

// Put this in your init method
// In Javascript, first define the function, then attach it as a listener.
_javascriptListener = [NSString stringWithFormat:
    @"function %@() {\
         %@ = '%@';\
    };\
    window.addEventListener(\"load\", %@, false);",
        JAVASCRIPT_TEST_FUNCTION, JAVASCRIPT_TEST_VARIBLE, LOAD_COMPLETED, JAVASCRIPT_TEST_FUNCTION];

// Then use this:

- (void)webViewDidFinishLoad:(UIWebView *)webView;
{
    // Only want to attach the listener and function once.
    if (_javascriptListener) {
        [_webView stringByEvaluatingJavaScriptFromString:_javascriptListener];
        _javascriptListener = nil;
    }

    if ([[webView stringByEvaluatingJavaScriptFromString:JAVASCRIPT_TEST_VARIBLE] isEqualToString:LOAD_COMPLETED]) {
        NSLog(@"UIWebView object has fully loaded.");
    }
}

Мое решение:

- (void)webViewDidFinishLoad:(UIWebView *)webView
{
    if (!webView.isLoading) {
        // Tada
    }
}

Вы также можете использовать принятый ответ здесь: UIWebView - как определить последнее сообщение webViewDidFinishLoad? ...

В принципе, используйте свойство valuProgress, и когда это достигает 100, страница закончила загрузку ... См. Это руководство для справки.

Хотя он использует частную структуру, в соответствии с руководством есть некоторые приложения в App Store, которые используют его ...


Сделайте свой контроллер просмотра делегатом UIWebView. (Вы можете сделать это в Interface Builder или используя этот код в методе viewDidLoad:

[self.myWebView setDelegate:self];

Затем используйте метод, описанный в принятом ответе здесь: webViewDidFinishLoad: стрельба слишком скоро? ,

Код:

-(void) webViewDidFinishLoad:(UIWebView *)webView
{
    NSString *javaScript = @"function myFunction(){return 1+1;}";
    [webView stringByEvaluatingJavaScriptFromString:javaScript];

    //Has fully loaded, do whatever you want here
}

WKWebView вызывает делегат didFinish когда DOM readyState является interactive , что слишком рано для веб-страниц, загруженных javascripts. Нам нужно дождаться complete состояния. Я создал такой код:

func waitUntilFullyLoaded(_ completionHandler: @escaping () -> Void) {
    webView.evaluateJavaScript("document.readyState === 'complete'") { (evaluation, _) in
        if let fullyLoaded = evaluation as? Bool {
            if !fullyLoaded {
                DDLogInfo("Webview not fully loaded yet...")
                DispatchQueue.main.asyncAfter(deadline: .now() + 1, execute: {
                    self.waitUntilFullyLoaded(completionHandler)
                })
            } else {
                DDLogInfo("Webview fully loaded!")
                completionHandler()
            }
        }
    }
}

а потом:

func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
    DDLogInfo("Webview claims that is fully loaded")

    waitUntilFullyLoaded { [weak self] in
        guard let unwrappedSelf = self else { return }

        unwrappedSelf.activityIndicator?.stopAnimating()
        unwrappedSelf.isFullLoaded = true
    }
}