I have a table view with cells that have a webView in them, I want the height of the cell to match the height of the webView.
This is the code I use:
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCellWithIdentifier("newsCell") as! NewsTableViewCell cell.webView.loadHTMLString("test<br>test<br>test<br>test<br>test<br>test", baseURL: nil) cell.webView.delegate = self var webFrame = cell.webView.frame var cellFrame = cell.frame cell.frame = CGRectMake(cellFrame.origin.x, cellFrame.origin.y, cellFrame.width, webFrame.height + 20) cell.backgroundColor = UIColor.redColor() return cell } func webViewDidFinishLoad(webView: UIWebView) { println("finished loading") var frame = webView.frame frame.size.height = 1 webView.frame = frame var fittingSize = webView.sizeThatFits(CGSizeZero) frame.size = fittingSize webView.frame = frame var height: CGFloat = frame.height println(height) webView.frame = CGRectMake(frame.origin.x, frame.origin.x, frame.size.width, frame.size.height) newsTable.beginUpdates() newsTable.endUpdates() }
And this is the result: https://postimg.cc/image/8qew1lqjj/
The webView is the correct height but the cell isn't, How can I fix this problem?
TableView will resize cells itself, you just need implement tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat
delegate method.
Yes, you don't know the height of WebView initially, but you can calculate it and then ask TableView to reload cell. Something like this:
class TableViewController: UITableViewController, UIWebViewDelegate { var content : [String] = ["test1<br>test1<br>test1<br>test1<br>test1<br>test1", "test22<br>test22<br>test22<br>test22<br>test22<br>test22"] var contentHeights : [CGFloat] = [0.0, 0.0] // ... override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCellWithIdentifier("newsCell", forIndexPath: indexPath) as! NewsTableViewCell let htmlString = content[indexPath.row] let htmlHeight = contentHeights[indexPath.row] cell.webView.tag = indexPath.row cell.webView.delegate = self cell.webView.loadHTMLString(htmlString, baseURL: nil) cell.webView.frame = CGRectMake(0, 0, cell.frame.size.width, htmlHeight) return cell } override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat { return contentHeights[indexPath.row] } func webViewDidFinishLoad(webView: UIWebView) { if (contentHeights[webView.tag] != 0.0) { // we already know height, no need to reload cell return } contentHeights[webView.tag] = webView.scrollView.contentSize.height tableView.reloadRowsAtIndexPaths([NSIndexPath(forRow: webView.tag, inSection: 0)], withRowAnimation: .Automatic) } // ... }
Swift 4
ifau's Answer modified for Swift 4, using UITableView
instead of UITableViewController
.
In storyboard, take a UITableView
. Add 1 prototype cell to it. Keep the reuseIdentifier of the cell to "cell
". Drag a webView
into the cell and set leading, trailing, top and bottom constraints to 0. Set the cell class to TableViewCell
TableViewCell.swift
Connect webView outlet to storyboard:
import UIKit class TableViewCell: UITableViewCell { @IBOutlet weak var webView: UIWebView! override func awakeFromNib() { super.awakeFromNib() // Initialization code } override func setSelected(_ selected: Bool, animated: Bool) { super.setSelected(selected, animated: animated) // Configure the view for the selected state } }
ViewController.swift
Connect the tableView outlet to the storyboard:
import UIKit class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, UIWebViewDelegate { @IBOutlet weak var tableView: UITableView! var content : [String] = ["test1<br>test1<br>test1", "test22<br>test22<br>test22<br>test22<br>test22<br>test22"] var contentHeights : [CGFloat] = [0.0, 0.0] override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. tableView.dataSource = self tableView.delegate = self } public func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int{ return content.count } public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell{ let cell : TableViewCell = tableView.dequeueReusableCell(withIdentifier: "cell") as! TableViewCell let htmlString = content[indexPath.row] let htmlHeight = contentHeights[indexPath.row] cell.webView.tag = indexPath.row cell.webView.delegate = self cell.webView.loadHTMLString(htmlString, baseURL: nil) cell.webView.frame = CGRect(x: 0, y: 0, width: cell.frame.size.width, height: htmlHeight) return cell } func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { if contentHeights[indexPath.row] != 0 { return contentHeights[indexPath.row] } } public func webViewDidFinishLoad(_ webView: UIWebView){ if (contentHeights[webView.tag] != 0.0) { // we already know height, no need to reload cell return } contentHeights[webView.tag] = webView.scrollView.contentSize.height tableView.reloadRows(at: [IndexPath(row: webView.tag, section: 0)], with: .automatic) } }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With