0

I'm displaying some markdown that the user wrote in a table view. The way I display these markdown texts is to convert the markdown to HTML and then display the HTML on a UIWebview. Because, well, I can use some cool CSS.

After some research, I found that I can set estimatedRowHeight to some stuff and set rowHeight to UITableViewAutomaticDimension. I also found out how to set a UIWebView's frame so that it fits its content here:

So I wrote this code:

var results: [Entry] = []

override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
    return 1
}

override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return results.count
}

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCellWithIdentifier("resultCell")
    let webView = cell?.contentView.viewWithTag(1) as! UIWebView
    let entry = results[indexPath.row]
    webView.loadHTMLString(entry.htmlDescription, baseURL: nil)
    webView.delegate = self
    
    return cell!
}

override func viewDidAppear(animated: Bool) {
    super.viewDidAppear(animated)
    tableView.reloadData()
}

override func viewDidLoad() {
    tableView.estimatedRowHeight = 400
    tableView.rowHeight = UITableViewAutomaticDimension
}

func webViewDidFinishLoad(webView: UIWebView) {
    let height = CGFloat(webView.stringByEvaluatingJavaScriptFromString("document.height")!.toFloat()!)
    var frame = webView.frame
    frame.size.height = height
    webView.frame = frame
    webView.scrollView.contentSize = frame.size
    webView.scrollView.frame = frame
    
    print(frame)
}

The results array is just the stuff I'm displaying. As you can see, I want to display the result's htmlDescription in each web view.

And in the webViewDidFinishLoad delegate method, I just did what the aforementioned post did: evaluating some JS and updating the web view's frame.

However, the behaviour is far from what I expected.

  • Firstly, the table view cells' heights are the default heights.
  • When I try to scroll the web views, I can't. They simply bounce back.
  • The console says that:

Warning once only: Detected a case where constraints ambiguously suggest a height of zero for a tableview cell's content view. We're considering the collapse unintentional and using standard height instead.

I don't know what is suggesting that the table view cell's height should be 0.

  • The console also prints the new frames of the web views. I only have 3 web views but there are 6 frames:

(0.0, 0.0, 320.0, 315.0)

(0.0, 0.0, 320.0, 363.0)

(0.0, 0.0, 320.0, 216.0)

(0.0, 0.0, 320.0, 315.0)

(0.0, 0.0, 320.0, 363.0)

(0.0, 0.0, 320.0, 216.0)

And the height seems to be pretty correct, not the default table view cell height.

I know that I can fix this if I could either:

  • know the content size of the web view before the HTML is loaded, or;
  • reload the table view when all web views finish loading. (Since I will possibly have lots of web views, I should call reloadData as less as possible or it will e very slow.)

How can I do this?

This is not a duplicate of How to make UITableViewCell adjust height to fit its content? because that question's table view is kind of static. Its content won't change once it is loaded. But mine has a web view which will load HTML.

Community
  • 1
  • 1
Sweeper
  • 213,210
  • 22
  • 193
  • 313
  • does your tableView take from an array? – Mohamad Bachir Sidani Jun 17 '16 at 13:55
  • You mean the `results` array? Yes! @BashirSidani – Sweeper Jun 17 '16 at 13:57
  • perfect! and does all cells have same height? – Mohamad Bachir Sidani Jun 17 '16 at 13:57
  • At the moment, yes (the default table view cell height). But I don't want them to. I want them to be the same as the height of the web view. And the height of the web view should be the same as the height of its content. @BashirSidani – Sweeper Jun 17 '16 at 13:59
  • you loop and calculate each cell height, then you can add them all up. After that add the height of the section if there is any. Then set the frame of the tableView as CGRectMake(yourTable.frame.origin.x, yourTable.frame.origin.y, yourTable.frame.sizewidth, calculatedHeight) – Mohamad Bachir Sidani Jun 17 '16 at 14:00
  • PS: If static multiply the array count with the static height for each cell – Mohamad Bachir Sidani Jun 17 '16 at 14:01
  • This doesn't work because 1. I can't get all the cell heights until the web view has loaded the HTML 2. I don't think setting the frame of the table view will have any effect on the table view cells. @BashirSidani If you think I misunderstood you, please post a detailed answer to explain. – Sweeper Jun 17 '16 at 14:05
  • when the html view is loaded are you able to get the desired height of it? – Mohamad Bachir Sidani Jun 17 '16 at 14:08
  • Yes... but the `webViewDidFinishLoad` method is called in a very weird way. You see, I have 3 web views but it is called 6 times. So I am not sure how to effectively sum the heights up. @BashirSidani – Sweeper Jun 17 '16 at 14:10

1 Answers1

0

Just calculate height in cellForRowAtIndex and set table.rowHeight. Look at this link can help you

Insert in a tableView set to Autoresize cause a scroll issue

Community
  • 1
  • 1
Marco Castano
  • 1,114
  • 1
  • 10
  • 25
  • But I need to wait until the web view has finish loading to know the height, right? And obviously, the web view is not loaded in `cellForRowAtIndexPath`. – Sweeper Jun 17 '16 at 23:55