如何根据内容在可变高度UITableView内确定UIWebView高度?

时间:2009-04-13 19:58:32

标签: ios iphone cocoa-touch uitableview uiwebview

我正在尝试根据this question

的答案中的说明创建一个具有可变高度行的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的{​​{1}}。 (如果细胞只调整到html内容的最大值,那也没关系,尽管可变高度会更好)。

7 个答案:

答案 0 :(得分:77)

这个代码对于表视图使用来说可能太慢了,但是这样做了。它看起来没有任何替代方案,因为UIWebView不提供对DOM的直接访问。

在视图控制器的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);
}

答案 1 :(得分:28)

我很高兴找到你的答案,javascript技巧对我有用。

但是,我想说还有“sizeThatFits:”方法:

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

我们必须设置一个不同于零的首选大小,但除此之外,它通常总是有效!

通常,因为使用UIWebViews,它似乎只在第二次加载时工作(我使用“loadHTMLString:”方法,是的,我从委托“didFinishLoad:”方法调用“sizeThatFits:”)。

所以,这就是为什么我很高兴找到适用于任何情况的解决方案。

答案 2 :(得分:6)

这似乎有效。现在。

- (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。

答案 3 :(得分:4)

-sizeThatFits:的问题在于它不能开箱即用,至少在iOS 4.1上不行。它只返回webView的当前大小(无论是使用CGSizeZero调用还是任意非零大小)。

我发现如果你在调用-sizeThatFits:之前减少webView的帧高,它确实有效。

请参阅我的解决方案:How to determine the content size of a UIWebView?

答案 4 :(得分:3)

如果你的sizeThatFits第一次但不是之后有错误的值,这可能是我遇到的原因:外部CSS的错误。 在检索外部CSS并完全构建Web文档之前,似乎很快就会调用webViewDidFinisLoad。 我认为如果因为缓存而重新加载,该错误​​就会消失。

技巧:很快在应用程序中使用虚拟UIWebView预加载CSS。

SDK:IOS4

答案 5 :(得分:3)

测量网页浏览有效,但仅在加载了内容

时才有效
  • 使webview变小(如5px)
  • 加载并等待完成
  • 在其上调用sizeToFit然后
  • 大小那么
  • 重新加载tableview(返回单元格的正确高度)

广告:: D看到我在github上的M42WebviewTableViewCell类与此挣扎

答案 6 :(得分:2)

更好的方法是使用scrollView.contentSize.height属性,如下所示。

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