简体   繁体   中英

Resizing UIWebView height to fit content

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.

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.

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 .

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.

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

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM