6

我正在构建一个应用程序,它将向用户显示一些时事通讯。时事通讯显示在 uiWebView 中。我正在阅读来自 rss 提要的时事通讯的网址。我解析 xml,在表格视图中我有所有的时事通讯。单击单元格时,将推送 uiWebView 并加载时事通讯。因为 uiWebView 没有打开具有 target=_blank 的链接,所以我需要将目标中的 _blank 替换为“”。在 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 和一个显示 Loading 的标签。下载完成后,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 *)webview {} 和 - webViewDiStartLoad 中加载页面

但是对于在 webview 中加载的每个项目都调用了这些方法,因此在这些方法中显示和隐藏 HUD 并不是一个好的解决方案。

我在使用时遇到了一些问题 - (BOOL)webView:(UIWebView*)webView shouldStartLoadWithRequest:(NSURLRequest*)request navigationType:(UIWebViewNavigationType)navigationType { ... return NO }

例如,具有 /bilder-galerien 这样的路径的链接不起作用,并且在 NSLog 中我为他们收到了这个

未知方案,什么都不做:/bilder-galerien

但是当我使用

  • (BOOL)webView:(UIWebView*)webView shouldStartLoadWithRequest:(NSURLRequest*)request navigationType:(UIWebViewNavigationType)navigationType { return Yes } 和 didstartLoading 和 finishLoading 加载了网址,我不知道为什么...

另一个问题是特殊的德语字符..在我的第一次加载中(在 uiTableView 中按下单元格后)页面被解析为应该由 uiWebView 但在我单击链接并加载相应的请求后字符也不是正确解析..

谁能指出我正确的方向?先感谢您

4

2 回答 2

4

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];
}
于 2010-04-22T11:04:53.893 回答
3

我喜欢 SorinA 的回答,我们可以通过以下方式使它变得更好:

  • 避免用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]'))"];
}
于 2010-08-17T20:35:42.283 回答