6

ユーザーにニュースレターを表示するアプリを作成しています。ニュースレターはuiWebViewに表示されます。RSSフィードからニュースレターのURLを読んでいます。xmlを解析すると、テーブルビューにすべてのニュースレターが表示されます。セルがクリックされると、uiWebViewがプッシュされ、ニュースレターが読み込まれます。uiWebViewはtarget=_blankを持つリンクを開かないため、targetの_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がページのコンテンツをダウンロードしている間、アクティビティインジケーターとLoadingを示すラベルが付いたHUDが表示されます。ダウンロードが完了すると、HUDはスーパービューから削除されます。

これまでのところ良いですが、ここに質問があります。webDidFinishLoadingへの最後の呼び出しを特定できなかったため、コールバック関数でNSOperationを使用しました(この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でこの問題が発生し、Webページが正しく表示されませんでしたか?

- (BOOL)webView:(UIWebView*)webView shouldStartLoadWithRequest:(NSURLRequest*)request navigationType:(UIWebViewNavigationType)navigationType{ return YES; } -(void)webViewDidFinishLoad:(UIWebView *)webview{}および-webViewDiStartLoadを使用してページをロードしてみました

ただし、メソッドはWebビューにロードされるすべてのアイテムに対して呼び出されるため、これらのメソッドでHUDを表示および非表示にすることは適切なソリューションではありません。

-(BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request NavigationType:(UIWebViewNavigationType)navigationType {...returnNO}の使用中にいくつかの問題が発生しました

たとえば、この/ billder-galerienのようなパスが機能しないリンクがあり、NSLogでこれを受け取ります

不明なスキーム、何もしない:/ billder-galerien

しかし、私が使用するとき

  • (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request NavigationType:(UIWebViewNavigationType)navigationType {return Yes} and didstartLoading and finishLoading urlsが読み込まれ、理由がわかりません...

もう1つの問題は、ドイツ語の特殊文字です。最初のロード(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の答えが好きです、私たちはそれをさらに良くすることができます:

  • で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]'))"];
}
于 2010-08-17T20:35:42.283 に答える