具有UIWebView动态高度的UITableViewCell

时间:2015-09-13 10:38:29

标签: ios xcode swift uitableview uiwebview

我有一个包含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()
}    

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

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

8 个答案:

答案 0 :(得分:3)

它为我工作,轻松地在WebView上加载动态的Html字符串。

首先在TableViewCell中使用带有滚动禁用的textView,然后使用ContentView在所有4面上采用WebView,Apply Zero约束。现在为textview和WebView提供相同的高度约束。现在为两个视图提供相同的文本,如下面的代码所示。

对于Clean UI隐藏textView来自XIB或storyBoard。

git

答案 1 :(得分:2)

Swift 4

ifau的使用UITableView代替UITableViewController为Swift 4修改了答案。

在故事板中,选择UITableView。添加1个原型单元格。将单元格的reuseIdentifier保持为“cell”。将webView拖到单元格中,将前导,尾随,顶部和底部约束设置为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
    }

}

<强> ViewController.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)
    }
}

答案 2 :(得分:1)

计算webview的高度使用DispatchQueue 重新加载tableViewcell的高度DispatchQueue.main.async。它可以避免异常的空格并在重新加载webview框架时崩溃

func webViewDidFinishLoad(_ webView: UIWebView)
{
    var frame : CGRect = webVwModule.frame;
    frame.size.height = 1;
    self.webVwModule.frame.size = webVwModule.sizeThatFits(.zero)
    frame.size = self.webVwModule.frame.size;
    webView.frame = frame;
    webViewContentHeight = self.webVwModule.frame.size.height;
    isWebViewLoaded = true

    DispatchQueue.main.async(execute: { () -> Void in
       self.tableView.beginUpdates()
        self.tableView.endUpdates()
    })
    }

override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {

        return webViewContentHeight!
}

答案 3 :(得分:0)

var heightOfWebview=0    

func webViewDidFinishLoad(_ aWebView: UIWebView)
{
    var frame: CGRect = aWebView.frame
    frame.size.height = 1
    aWebView.frame = frame
    let fittingSize = aWebView.sizeThatFits(CGSize.zero)
    frame.size = fittingSize
    aWebView.frame = frame
    heightOfWebview = Int(fittingSize.height)
    tableView.beginUpdates()
    tableView.endUpdates()
    print("Calling webViewDidFinishLoad. Cell size value: \(heightOfWebview)")

}
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat
{
    return CGFloat(220+heightOfWebview) /// 220 is my static value
}

答案 4 :(得分:0)

最好的方式对我有用。

var heightOfWebview: CGFloat = 0    

func webViewDidFinishLoad(_ aWebView: UIWebView)
{
    var frame: CGRect = aWebView.frame
    frame.size.height = 1
    aWebView.frame = frame
    let fittingSize = aWebView.sizeThatFits(CGSize.zero)
    frame.size = fittingSize
    aWebView.frame = frame
    heightOfWebview = Int(fittingSize.height)
    tableView.beginUpdates()
    tableView.endUpdates()
    print("Calling webViewDidFinishLoad. Cell size value: \(heightOfWebview)")

}
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat
{
    return heightOfWebview
}

答案 5 :(得分:0)

最简单优雅的方式是

  1. 为webview添加高度布局约束
  2. 添加webview委托完成加载,然后将contentSize height设置为高度布局约束的常量。

  3. 保留tableview的实例或对主表视图进行委托 - 块 - 闭包。

  4. 调用tableview beginupdate endupdate让tableview知道他们应该验证布局。
  5. class WebViewTableViewCell: UITableViewCell {
        weak var viewController: ViewController? = nil
        @IBOutlet weak var webView: UIWebView!
        @IBOutlet weak var heightLayoutConstraint: NSLayoutConstraint!
        
        override func awakeFromNib() {
            super.awakeFromNib()
            webView.loadRequest(URLRequest(url: URL(string: "https://tinhte.vn")!))
            webView.delegate = self
            webView.scrollView.isScrollEnabled = false
            // Initialization code
        }
    
        override func setSelected(_ selected: Bool, animated: Bool) {
            super.setSelected(selected, animated: animated)
    
            // Configure the view for the selected state
        }
    
    }
    extension WebViewTableViewCell: UIWebViewDelegate {
        func webViewDidFinishLoad(_ webView: UIWebView) {
            heightLayoutConstraint.constant = webView.scrollView.contentSize.height
            viewController?.tableView.beginUpdates()
            viewController?.tableView.endUpdates()
        }
    }

答案 6 :(得分:0)

我还有一个您应该考虑的解决方案。设置高度限制,并将其链接到您的UITableViewCell类。然后实现委托方法func webViewDidFinishLoad(_ webView: UIWebView),并在调用该方法时将高度约束设置为等于webView.scrollView.contentSize.height

答案 7 :(得分:0)

class WebViewTableViewCell: UITableViewCell {
    weak var viewController: ViewController? = nil
    @IBOutlet weak var webView: UIWebView!
    @IBOutlet weak var heightLayoutConstraint: NSLayoutConstraint!
    
    override func awakeFromNib() {
        super.awakeFromNib()
        webView.loadRequest(URLRequest(url: URL(string: "https://tinhte.vn")!))
        webView.delegate = self
        webView.scrollView.isScrollEnabled = false
        // Initialization code
    }

    override func setSelected(_ selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)

        // Configure the view for the selected state
    }

}
extension WebViewTableViewCell: UIWebViewDelegate {
    func webViewDidFinishLoad(_ webView: UIWebView) {
        heightLayoutConstraint.constant = webView.scrollView.contentSize.height
        viewController?.tableView.beginUpdates()
        viewController?.tableView.endUpdates()
    }
}