10

I'm loading an HTML string of arbitrary length into a UIWebView which is then displayed in a UITableViewCell. I do not want this UIWebView to scroll independently of the UITableView so I must resize its height to fit the content.

This UITableViewCell is also collapsable, not showing the UIWebView when it's in its collapsed state.

The rub is, how do I know what this height is so that I can have heightForRowAtIndexPath return a proper value and allow the table to look and scroll correctly?

Here's some example code:

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.row == 0)
    return 286;

if (indexPath.row == 1) {
    if (analysisExpanded)
        return analysisWebViewHeight + 39;
    else 
        return 52;
}

if (sourcesExpanded)
    return sourcesWebViewHeight + 39;

return 53;

}

Pretty simple. The 39 is the height of some header stuff I have in the cell with the webview.

I am loading the "expanded view" of the cell from a nib, so to get the webview I'm calling viewForTag:

        UIWebView* sourcesWebView = (UIWebView*)[cell viewWithTag:1];
        [sourcesWebView setBackgroundColor:[UIColor clearColor]];
        [sourcesWebView loadHTMLString:placeholder baseURL:[NSURL URLWithString:@"http://example.com/"]];
        sourcesWebViewHeight = [[sourcesWebView stringByEvaluatingJavaScriptFromString:@"document.documentElement.scrollHeight"] floatValue];
        [sourcesWebView setFrame:CGRectMake(sourcesWebView.frame.origin.x, sourcesWebView.frame.origin.y, sourcesWebView.frame.size.width, sourcesWebViewHeight)];

sourcesWebViewHeight is an iVar that is updated by the above code in cellForRowAtIndexPath. If the user taps the cell three times, expand-collapse-expand, and does a little scrolling, eventually it gets the correct height.

I tried "Preloading" the height by using a memory-only UIWebView object, but that never returned correct numbers for some reason.

Venk
  • 5,949
  • 9
  • 41
  • 52
James
  • 6,471
  • 11
  • 59
  • 86
  • Apple(in UIWebView documentation) strictly said not to use UIWebView in the UITableView. – makboney Nov 29 '11 at 10:51
  • we've published several apps with web-views as cells without any issues – Denis Nov 29 '11 at 12:09
  • More and better answers to same question can be found [here][1] as well. [1]: http://stackoverflow.com/questions/3936041/how-to-determine-the-content-size-of-a-uiwebview – i-- Nov 20 '13 at 14:37

4 Answers4

5

The issue was that I was attempting to get the scroll size before the web view had a chance to render it.

After implementing the didFinishLoad delegate method, my original javascript worked fine to get the height.

James
  • 6,471
  • 11
  • 59
  • 86
2

For iOS Safari you need to use the following line:

NSInteger height = [[sourcesWebView stringByEvaluatingJavaScriptFromString:@"document.body.offsetHeight;"] integerValue];

document.documentElement.scrollHeight is not working for this browser.

Just to be sure everything is right, you need to call this after your web-view has finished loading =)

UPDATE: another option, that will work only for iOS5, they've added scrollView property to the UIWebView, where you can get contentSize.

Denis
  • 6,313
  • 1
  • 28
  • 27
1

Since webViewDelegate can get the height of webView when HTML code is loaded, the tableview:heightForRowAtIndexPath: method will enter an infinite loop for trying to retrieve the webView located in the tableView Cell:

- (float)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    float height;

    UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
    UIWebView *webContent = (UIWebView *) [cell viewWithTag:tagTableSingleContentWeb];
    CGRect frame = webContent.frame;

    height = frame.origin.y + frame.size.height + 30;

    return height;
}

The above is the code I tried to change the tableView cell when I insert HTML code into the webView inside tableView cell, but it will cause infinite loop....

I am still trying to find out some other way.

p.s. WebViewDelegate way is ok when webView is located in ScrollView, but I do not how to make it work for inside TableView cell yet.

Venk
  • 5,949
  • 9
  • 41
  • 52
Dennies Chang
  • 564
  • 5
  • 15
0

More and better answers to pretty much same question can be found here as well. Just thought it might be helpful for someone.

Community
  • 1
  • 1
i--
  • 4,349
  • 2
  • 27
  • 35