具有UIWebView动态高度的UITableViewCell

Ome*_*erN 19 xcode uiwebview uitableview ios swift

我有一个表格视图,其中包含webView的单元格,我希望单元格的高度与webView的高度相匹配.

这是我使用的代码:

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()
}    
Run Code Online (Sandbox Code Playgroud)

这就是结果:https://postimg.cc/image/8qew1lqjj/

webView是正确的高度,但单元格不是,我该如何解决这个问题?

ifa*_*fau 23

TableView将调整单元格本身,您只需要实现tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat委托方法.

是的,您最初不知道WebView的高度,但您可以计算它,然后让TableView重新加载单元格.像这样的东西:

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)
    }

    // ...
}
Run Code Online (Sandbox Code Playgroud)


Dia*_*Dia 7

斯威夫特 4

ifau 的答案针对 Swift 4 进行了修改,使用UITableView代替UITableViewController.

在故事板中,取一个UITableView. 向其中添加 1 个原型单元格。保持单元格的重用标识符为“ cell”。将 awebView拖入单元格并将前导、尾随、顶部和底部约束设置为 0。将单元格类设置为TableViewCell

TableViewCell.swift

将 webView 插座连接到故事板:

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
    }

}
Run Code Online (Sandbox Code Playgroud)

视图控制器.swift

将 tableView 插座连接到故事板:

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)
    }
}
Run Code Online (Sandbox Code Playgroud)