UIWebViewDelegate: webViewDidFinishLoad не вызывается во время навигации по страницам

У меня есть приложение, в котором пользователи могут перемещать кучу локально сохраненных файлов HTML. У меня есть UIWebView, правильно настроенный с помощью UIWebViewDelegate. Обычно, когда пользователь следует за ссылкой, вызывается shouldStartLoadWithRequest, а затем webViewDidFinishLoad чуть позже.

Но если ссылка указывает на привязку на той же странице, что и отображаемая в данный момент, вызывается только shouldStartLoadWithRequest. webViewDidFinishLoad не срабатывает.

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

Мой лучший хакер до сих пор заключался в вызове performSelector: withObject: afterDelay: в конце моего метода shouldStartLoadWithRequest, но я не доволен этим.

Кто-нибудь знает, как я могу это правильно решить? Любое понимание было оценено!

Ответ 1

Вы можете попробовать использовать NSURLConnectionDataDelegate, он позволяет обрабатывать входящие данные. Возможно, вы можете определить, загружена ли страница вручную, добавив знак в ваши html файлы.

Справка NSURLConnectionDataDelegate

Изменить: gist.github.com/buranmert/7304047 Я написал часть кода, и это сработало, возможно, это не так, как вы хотели, чтобы он работал, но возможно, это помогает. Каждый раз, когда пользователь нажимает на URL с якорем, он создает другое соединение, и по завершении подключения загрузка веб-представления загружает данные, что указывает на то, что веб-представление закончило загрузку страницы. Поскольку вы используете только локальные html файлы, я не думаю, что создание соединений создаст проблемы.

Ответ 2

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

Нагрузки, выполняемые в iFrame DO, запускают все методы делегатов, и это дает вам решение. Вы можете использовать этот механизм для отправки уведомлений на собственный код, как это часто делается для console.log(), как описано в этом сообщении. В качестве альтернативы Native Bridge будет хорошо работать, чтобы вызвать ваш код Objective C из JavaScript.

Ответ 3

Просто проверьте погоду и получим функцию делегата DidStartLoading, если она вызвана без сомнения, что DidFinish также должен быть вызван

Ответ 4

Вы уверены, что ваш shouldStartLoadWithRequest всегда возвращает ДА ​​???

Я всегда добавляю

return YES;

в конце shouldStartLoadWithRequest. И это работает для меня. Возвращая YES, это означает, что веб-просмотр загружен и вызовет webViewDidFinishLoad

Ответ 5

if([webView isLoading]==1)
{
    //your webview is loading
}
else
{
   //your webview has loaded
}

Ответ 6

Вот быстрая реализация кода Mert Buran, если кто-то ее ищет. (Хотя NSURLConnection устарел с iOS 9)

Но это не решает мою проблему. Когда я нажимаю на ссылку jquery, которая всплывает из видео, она не запускает webViewDidFinishLoad.

class WebViewController: UIViewController, UIWebViewDelegate, NSURLConnectionDelegate {

var menuURL: String?

var response: NSURLResponse?
var data = NSData()

// MARK: Properties
@IBOutlet weak var webView: UIWebView!

override func viewDidLoad() {
    super.viewDidLoad()

    webView.delegate = self

    // From Web
    let url = NSURL (string: menuURL!)
    let urlRequest = NSURLRequest(URL: url!)

    let connection = NSURLConnection(request: urlRequest, delegate: self)
    self.data = NSData()
    connection!.start()

    // if this is false, page will be 'zoomed in' to normal size
    webView.scalesPageToFit = false

}

func webView(webView: UIWebView, shouldStartLoadWithRequest request: NSURLRequest, navigationType: UIWebViewNavigationType) -> Bool {
    if navigationType == .LinkClicked && request.URL!.fragment != nil {
        let connection = NSURLConnection(request: request, delegate: self)
        connection!.start()
        return false
    }
    return true
}

func connection(connection: NSURLConnection, didReceiveResponse response: NSURLResponse) {
    self.response = response
}

func connection(connection: NSURLConnection, didReceiveData data: NSData) {
    let oldData = NSMutableData(data: self.data)
    oldData.appendData(data)
    self.data = oldData
}

func connectionDidFinishLoading(connection: NSURLConnection) {
    self.webView.loadData(self.data, MIMEType: self.response!.MIMEType!, textEncodingName: "utf-8", baseURL: self.response!.URL!)
    self.data = NSData()
}


}