web-dev-qa-db-ja.com

可変の高さのUITableView内で、コンテンツに基づいてUIWebViewの高さを決定する方法は?

この質問 への答えで説明されているように、可変高行を持つUITableViewを作成しようとしています

私の問題は、各セルに異なる(静的にロードされた)コンテンツを持つUIWebViewが含まれていることです。コンテンツに基づいて適切な高さを計算する方法がわかりません。これを行う方法はありますか?私はこのようなことを試しました:

   (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
       WebViewCell *cell = (WebViewCell*)[self tableView:tableView cellForRowAtIndexPath:indexPath];
       [cell setNeedsLayout];
       [cell layoutIfNeeded];
       return cell.bounds.size.height;
    }

セル自体は、UITableViewCellを含むUIWebViewであるペン先からロードされます。 (可変の高さの方が良いとはいえ、セルが最大のhtmlコンテンツに合わせて調整された場合でも問題ありません)。

69
frankodwyer

このコードは、おそらくテーブルビューの使用には遅すぎますが、トリックは行います。 UIWebViewはDOMへの直接アクセスを提供しないため、代替手段があるようには見えません。

View ControllerのviewDidLoadで、WebViewにHTMLをロードし、ロードが完了したらJavaScriptを実行して要素の高さを返します。

- (void)viewDidLoad
{
    [super viewDidLoad];
    webview.delegate = self;
    [webview loadHTMLString:@"<div id='foo' style='background: red'>The quick brown fox jumped over the lazy dog.</div>" baseURL:nil];
}

- (void)webViewDidFinishLoad:(UIWebView *)webView
{
    NSString *output = [webview stringByEvaluatingJavaScriptFromString:@"document.getElementById(\"foo\").offsetHeight;"];
    NSLog(@"height: %@", output);
}
77
duncanwilcox

私はあなたの答えを見つけてとてもうれしかったです、javascriptトリックは私のためにうまくいきました。

ただし、「sizeThatFits:」メソッドもあると言いたかったのです。

CGSize goodSize = [webView sizeThatFits:CGSizeMake(anyWidth,anyHeigth)];

ゼロとは異なる優先サイズを設定する必要がありますが、それとは別に、通常は常に機能します!

通常、UIWebViewsでは、2回目の読み込みでのみ動作するようです(「loadHTMLString:」メソッドを使用し、はい、デリゲート「didFinishLoad:」メソッドから「sizeThatFits:」を呼び出します)。

だから、だからこそ、どんな場合でも機能するあなたのソリューションを見つけることができてとても嬉しかったです。

28
Unfalkster

これはうまくいくようです。今のところ。

- (void)webViewDidFinishLoad:(UIWebView *)webView
{
    CGFloat webViewHeight = 0.0f;
    if (self.subviews.count > 0) {
        UIView *scrollerView = [self.subviews objectAtIndex:0];
        if (scrollerView.subviews.count > 0) {
            UIView *webDocView = scrollerView.subviews.lastObject;
            if ([webDocView isKindOfClass:[NSClassFromString(@"UIWebDocumentView") class]])
                webViewHeight = webDocView.frame.size.height;
        }
    }
}

失敗した場合、安全に0を返す必要があります。

6
Dave Batton

-sizeThatFits:の問題は、少なくともiOS 4.1では、そのままでは機能しないことです。 WebViewの現在のサイズを返します(CGSizeZeroで呼び出された場合でも、ゼロ以外の任意のサイズで呼び出された場合でも)。

-sizeThatFits:を呼び出す前にwebViewのフレームの高さを減らすと、実際に機能することがわかりました。

私の解決策を参照してください: IWebViewのコンテンツサイズを決定する方法?

4
Ortwin Gentz

SizeThatFitsで最初に悪い値を持っているが、その後ではない場合、ここで私が遭遇した考えられる原因:外部CSSのバグ。外部CSSが取得され、Webドキュメントが完全に構築される前に、webViewDidFinisLoadがすぐに呼び出されるようです。キャッシュのためにリロードするとバグは消えると思います。

秘::アプリケーションで間もなくダミーのUIWebViewを使用してCSSをプリロードします。

SDK:IOS4

3
Kabhal

ウェブビューの測定は機能しますが、コンテンツをロードした場合のみ

  • webViewを小さくする(5pxなど)
  • ロードして終了を待つ
  • 次に、sizeToFitを呼び出します
  • サイズを取得する
  • テーブルビューを再読み込みします(セルの正しい高さを返します)

広告::D githubのM42WebviewTableViewCellクラスを参照してください。

3
Daij-Djan

より良いアプローチは、以下のようなscrollView.contentSize.heightプロパティを使用することです。

- (void)webViewDidFinishLoad:(UIWebView *)webView
{
     NSLog(@"%f",webView.scrollView.contentSize.height);   
}
2
Ans