Правильная загрузка текста в WKWebView

Я использую этот код для загрузки моего html файла с текстом в WKWebView:

do {
   guard let filePath = Bundle.main.path(forResource: "\(readBookNumber)", ofType: "html")
       else { 
           print ("File reading error")
           return
       }
   var content =  try String(contentsOfFile: filePath, encoding: .utf8)
   let baseUrl = URL(fileURLWithPath: filePath)
            
   content.changeHtmlStyle(font: "Iowan-Old-Style", fontSize:  UserDefaults.standard.integer(forKey: "textSize"), fontColor: textColor)
   webView.loadHTMLString(headerString+content, baseURL: baseUrl)
}
catch {
    print ("File HTML error")
}

и этот код для загрузки страницы, на которой пользователь остановил чтение в последний раз:

self.webView.scrollView.contentOffset.x = CGFloat(UserDefaults.standard.integer(forKey: "pageToLoad"))

Я использую код для загрузки последней страницы в этом методе:

func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
    DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
         self.webView.scrollView.contentOffset.x = CGFloat(UserDefaults.standard.integer(forKey: "pageToLoad"))
    }
}

Сначала я использовал deadline: .now() + 0.1, но это не сработало. Потому что изначально была загружена последняя прочитанная страница, и через несколько секунд я вижу что этот текст пересколчил на первую страницу. Я меняю deadline: .now() + 0.5 и текст загружается нормально с последней прочитанной страницы. У меня было 700 страниц. Но теперь я хочу загрузить другой текст на 1700 страниц. И у меня такая же проблема, как и в первый раз. Я могу изменить deadline: .now() + 1.0 и мой текст загрузится нормально. Но я думаю, что это не лучшее решение. Сейчас запускаю приложение на своем iPhone X. Но, возможно, если запущу его на iPad mini 2, мне стоит изменить deadline: .now() + 10.0 или что-то в этом смысле потому что iPad mini 2 не очень мощный. Как решить проблему?


Ответы (1 шт):

Автор решения: schmidt9

Попробуйте решение с определением contentSize, изменение которого будет означать, что файл загрузился, поскольку на момент вызова метода func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) размер контента внутри webView.scrollView еще равен нулю, поэтому листать некуда.

Мы добавляем 2 переменные

private var contentSizeObservationToken: NSKeyValueObservation!
private var isLoading = true

И затем используем наблюдение при инициализации веб вью

        contentSizeObservationToken = webView.scrollView.observe(\.contentSize, options: .new) {scrollView, _ in
            if self.isLoading {
                self.isLoading = false
                
                DispatchQueue.main.async {
                    scrollView.contentOffset.x = CGFloat(UserDefaults.standard.integer(forKey: "pageToLoad"))
                }
            }
        }

Также добавляем метод

    deinit {
        contentSizeObservationToken.invalidate()
    }

Для справки обсуждение вопроса с определением загрузки WKWebView

→ Ссылка