mclin ответ верен в том, что UIWebView выполняет нагрузки в фоновом режиме.Если все, что вы загружаете, - это обычный html, и ни у одного тега нет содержимого типа src = "...", то вы можете быть вполне уверены, что webViewDidFinishLoad (метод протокола UIWebViewDelegate) будет вызываться только один раз, и что вы можете выполнить свой javascript в этом делегате.method.
Однако после загрузки исходного HTML-кода UIWebView начнет загружать любые изображения, javascript, аудио, видео и т. д., а webViewDidFinishLoad будет вызываться при завершении каждой из последующих загрузок.Я думаю, что если вы посмотрите на индикатор прогресса Safari на вашем iPhone, вы сможете увидеть это поведение.Индикатор выполнения идет примерно на полпути после начальной загрузки страницы, а затем идет постепенно по мере загрузки изображений или того, что вы загрузили.
Я попробовал несколько методов для запуска javascript послезагрузка страницы завершена.Проще всего сделать так, чтобы webViewDidFinishLoad через короткую задержку выполнил другой селектор и проверил свойство загрузки webView.Здесь вы рискуете тем, что мы объединяем «сроки» и «темы», но эй ... если вы хотите легко (то есть).
-(void) checkIfLoadDone:(UIWebView *) webView {
if (webView.loading) { return; }
// run your javascript here
}
-(void) webViewDidFinishLoad:(UIWebView *) webView {
[NSObject cancelPreviousPerformRequestsWithTarget:self
selector:@selector(checkIfLoadDone:)
object:webView];
[self performSelector:@selector(checkIfLoadDone:)
withObject:webView
afterDelay:0.5];
}
-(void) webViewDidStartLoad:(UIWebView *)webView {
[NSObject cancelPreviousPerformRequestsWithTarget:self
selector:@selector(checkIfLoadDone:)
object:webView];
}
- (void) webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error {
// ooops ... probably should deal with the error, but lets just run checkIfLoadDone
[NSObject cancelPreviousPerformRequestsWithTarget:self
selector:@selector(checkIfLoadDone:)
object:webView];
[self performSelector:@selector(checkIfLoadDone:)
withObject:webView
afterDelay:0.5];
}
Более сложная техникаэто отслеживать нагрузки индивидуально и вести счетчик.Когда счетчик возвращается к 0, вы можете запустить свой JavaScript.В этом случае вы захотите реализовать метод делегата для
- (BOOL) webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
if (navigationType != UIWebViewNavigationTypeOther) {
self.outStandingLoads = 0;
}
return YES;
}
. Теперь вы можете иметь webViewDidStartLoad: increment outStandingLoads и иметь webViewDidFinishLoad: и webView: didFailLoadWithError: decment и checkSSignLoads.Я бы использовал атомарное свойство NSInteger для outStandingLoads по всему коду, чтобы учесть потенциальную возможность загрузки более одного потока.
Я думаю, что любой из методов будет работать достаточно хорошо.Я выбрал последний подход, но только потому, что мне нужно было решить другие проблемы в вызовах webViewDelegate.Я решил расширить UIWebView и сделать его своим собственным делегатом, где мое расширение реализовало методы делегата.Затем я использую модель NSNotification для публикации уведомлений, таких как «WebPageLoadBegan» и «WebPageLoadComplete», для связи с моим кодом пользовательского интерфейса.Мне показалось, что это более простая модель при работе с двумя различными наборами кода пользовательского интерфейса ... iPad и iPhone.
Надеюсь, это поможет.