UIWebView загрузка разобранная строка html - PullRequest
6 голосов
/ 18 июля 2009

Я создаю приложение, которое будет отображать некоторые информационные бюллетени для пользователей. новостные рассылки отображаются в uiWebView. Я читаю ссылки на рассылку новостей из RSS-ленты. Я анализирую XML, и в табличном представлении у меня есть все информационные бюллетени. При нажатии на ячейку uiWebView выдвигается, и информационный бюллетень загружается. Поскольку uiWebView не открывает ссылки, которые имеют target = _blank, мне нужно заменить _blank from target на "". В NSOperation я загружаю содержимое HTML и после завершения загрузки я заменяю строки следующим образом:

NSMutableString *page = [[[NSMutableString alloc] initWithData:pageData encoding:NSISOLatin1StringEncoding] autorelease]; [page replaceOccurrencesOfString:@"target=_blank" withString:@"target=""" options:0 range:NSMakeRange(0, [page length])];

после этого я загружаю проанализированную строку в webView, чтобы отобразить ее пользователю.

[myWebView loadHTMLString:page baseURL:[NSURL URLWithString:@""]];

в то время как NSOperation загружает содержимое страницы, HUD с индикатором активности и надписью, показывающей загрузку. После завершения загрузки HUD удаляется из суперпредставления.

пока все хорошо ... но вот вопросы. я использовал NSOperation с функцией обратного вызова, потому что я не смог определить последний вызов webDidFinishLoading (я прочитал это UIWebView - Как определить «последнее» сообщение webViewDidFinishLoad? - это часть моего проблема, но ответом было использование некоторых частных классов Apple, и это проблема для меня). так что я делаю это:

- (BOOL)webView:(UIWebView*)webView shouldStartLoadWithRequest:(NSURLRequest*)request navigationType:(UIWebViewNavigationType)navigationType {


NSURL *url = request.URL;
NSString *urlString = url.absoluteString;
NSLog(@"WebViewSouldStartWithRequest: %@", urlString);
if (navigationType == UIWebViewNavigationTypeLinkClicked)
{
    if(![urlString isEqualToString:@"about:blank"])
    {
        NSLog(@"FeedViewController: startPageLoad");
        activityHud = [[HUDView alloc] initWithFrame:CGRectMake(110, 100, 80, 80)];
        [activityHud setText:@"Loading"];
        [myWebView addSubview:activityHud];
        NSLog(@"FeedViewController: pageUrl = %@", urlString);
        [self resetWebView];
        [urlLoader loadPageFromUrl:request.URL withCallbackTarget:self withCallbackSelector:@selector(endLoading:)];
    }
}

return NO;

}

- (void) endLoading:(NSMutableString *)page { [self resetWebView]; NSLog(@"FeedViewController: endLoading"); [activityHud removeFromSuperview]; [myWebView loadHTMLString:page baseURL:[NSURL URLWithString:@""]]; }

после того, как я касаюсь ячейки в табличном представлении и отображается информационный бюллетень, он выглядит так, как должен; когда я нажимаю ссылку в информационном бюллетене, страница загружается с новым запросом, анализируется, но визуально выглядит не так, как должно (Я посмотрел на страницу после синтаксического анализа в NSLog, и на ней есть стили css и html-теги, заголовок, тело открыты и закрыты правильно) У кого-нибудь была эта проблема с uiWebView, неправильно отображались веб-страницы?

я попытался загрузить страницу с помощью - (BOOL)webView:(UIWebView*)webView shouldStartLoadWithRequest:(NSURLRequest*)request navigationType:(UIWebViewNavigationType)navigationType{ return YES; } и в - (void) webViewDidFinishLoad: (UIWebView *) веб-просмотр {} и в - webViewDiStartLoad

но методы вызываются для каждого элемента, загруженного в веб-просмотр, поэтому показ и скрытие HUD в этих методах не является хорошим решением.

Я столкнулся с некоторыми проблемами при использовании - (BOOL) webView: (UIWebView *) webView shouldStartLoadWithRequest: (NSURLRequest *) запрос navigationType: (UIWebViewNavigationType) navigationType {... return NO}

например ссылки, которые имеют такие пути, как / bilder-galerien, чтобы не работать, и в NSLog я получаю это для них

Неизвестная схема, ничего не делая: / Билдер-Galerien

но когда я использую

  • (BOOL) webView: (UIWebView *) webView shouldStartLoadWithRequest: (NSURLRequest *) запрос navigationType: (UIWebViewNavigationType) navigationType {return Yes} и didstartLoading и finishLoading URL-адреса загружены, и я не знаю, почему ...

другая проблема - это специальные немецкие символы ... при моей первой загрузке (после нажатия ячейки в uiTableView) страница анализируется так, как это должно быть в uiWebView, но после того, как я щелкаю ссылку и соответствующий запрос загружается, также символы не анализируются правильно ..

Кто-нибудь может указать мне правильное направление? заранее спасибо

Ответы [ 2 ]

4 голосов
/ 22 апреля 2010

UIWebView не открывает target = "_ blank" ссылки. Некоторые ссылки не запускают события UIWebViewNavigationTypeLinkClicked. Это происходит, когда ссылка имеет атрибут target = "_ blank".

Чтобы обойти эту проблему, я использовал код ниже. Он вставляет некоторый JavaScript после загрузки страницы, чтобы удалить целевой атрибут из всех ссылок. После использования этого кода мне больше не нужно разбирать исходный код HTML и заменять _blank на _self, например.

- (void)webViewDidFinishLoad:(UIWebView *)webView {
        NSString *js = @"\
        var d = document.getElementsByTagName('a');\
        for (var i = 0; i < d.length; i++) {\
            if (d[i].getAttribute('target') == '_blank') {\
                d[i].removeAttribute('target');\
            }\
        }\
        ";

        [webView stringByEvaluatingJavaScriptFromString:js];
}
3 голосов
/ 18 августа 2010

Мне нравится ответ SorinA, мы можем сделать его еще лучше:

  • избегайте помехи JavaScript с помощью var d
  • поскольку мы знаем, что у нас работает движок webkit, мы можем использовать селекторы:

... поэтому в вашем методе протокола UIWebViewDelegate вызовите код js:

- (void) webViewDidFinishLoad: (UIWebView *) webView {
  [webView stringByEvaluatingJavaScriptFromString: @"(function($){for(var i=0;i<$.length;++i){$[i].removeAttribute('target')}})(document.querySelectorAll('a[target=_blank]'))"];
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...