Explicitly set row height for some rows but use estimatedRowHeight for others

2.1k views Asked by At

I have a UITableViewCell which contains a UIWebView as a subview. The web view fills the entire cell. I am using estimatedRowHeight to calculate the row height. However, at the time the table view is built, the cell has no height because the web view has not loaded it's content, therefore the cell has no content. Because of this, estimatedRowHeight returns 44 instead of the correct height of the web view content.

Does anyone know how I can correctly calculate the height of a row when the content is not immediately set? Is there a way to estimate the height of some cells and explicitly set the heigh of other cells, in the same table view?

This is how I am using estimatedRowHeight:

self.tableView.estimatedRowHeight = 200;
self.tableView.rowHeight = UITableViewAutomaticDimension;

I am not using the delegate method. I have tried it, but it does not change the result. The cell I am using has a xib which also uses Auto Layout constraints. To be clear, the cell does appear and the web view does get added to the cell. The problem is that the height of the cell is not big enough to show the entire web view. The web view loads an HTML embed code for an audio player.

2

There are 2 answers

3
tentmaking On BEST ANSWER

I did some fiddling around and found out that you can use UITableViewAutomaticDimension in the following way:

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    TableSection *tableSection = (self.tableModel.sections)[indexPath.section];

    if (tableSection.sectionType == TableSectionTypeWebView)
    {
        return 120;
    }
    else
    {
        return UITableViewAutomaticDimension;
    }
}

This basically says, use a height of 120 for any WebView sections but for everything else I want you to figure out the height. I am using a my own custom table model here (i.e. TableSection, sectionType, etc...)

I had to add self.tableView.estimatedRowHeight = 200; to my init method for that to work.

Now I can provide an estimated row height but also explicitly set a row height for some sections, or even some rows if I wanted.

I haven't seen any documentation for this, but I tested it with variable length strings and it held up just fine.

2
Shabarinath Pabba On

You make your class a UIWebViewDelegate and then in and set your class as a delegate to every single UIWebView in your UITableViewCell

-(void)webViewDidFinishLoad:(UIWebView *)aWebView {
    CGRect frame = aWebView.frame;
    frame.size.height = 1;
    aWebView.frame = frame;
    //Asks the view to calculate and return the size that best fits //its subviews.
    CGSize fittingSize = [aWebView sizeThatFits:CGSizeZero];
    frame.size = fittingSize;
    aWebView.frame = frame;
    [self.tableView beginUpdates];
    [self.tableView  endUpdates];
}

Now you can get the height of the UIWebView and set it to the rows height, because the following method will be called again once a 'beginUpdates' is invoked

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:  (NSIndexPath*)indexPath {
    return _webView.frame.size.height;
}

Hope This helps