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