UITableViewCell With UIWebView Dynamic Height

前端 未结 10 2042
深忆病人
深忆病人 2020-12-04 11:52

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:



        
相关标签:
10条回答
  • 2020-12-04 11:58
    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
    }
    
    0 讨论(0)
  • 2020-12-04 11:59

    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)
        }
    
        // ...
    }
    
    0 讨论(0)
  • 2020-12-04 11:59

    After calculating the height of webview Use DispatchQueue for reloading the tableViewcell height DispatchQueue.main.async.It avoids abnormal empty spaces and crash while reloading webview frame

    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!
    }
    
    0 讨论(0)
  • 2020-12-04 12:01

    The most easy and elegant way is

    1. Add height layout constraint for webview
    2. Add webview Delegate finished loading then set contentSize height to constant of height layout constraint.

    3. Keep instance of tableview or make a delegate - block - closure to main tableview.

    4. Call tableview beginupdate endupdate to let tableview know they should validate layout.

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

    0 讨论(0)
  • 2020-12-04 12:11

    It's work for me, easy Way to load Html String on WebView with dynamic.

    First take textView in TableViewCell with scroll disable and then take WebView, Apply Zero constraint on all 4 Side with ContentView. Now give same height constraint to both textview and WebView.Now give same text to both view as shown below code.

    For Clean UI Hide textView From XIB or storyBoard.

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 10
    }
    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        return UITableViewAutomaticDimension
    }
    func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
        return 100
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "tableviewcell") as! tableviewcell
        let theString : String = "</p><img src='https://pbs.twimg.com/profile_images/655066410087940096/QSUlrrlm.png' width=100 height=100 /><h2>Subheader</h2>"
    
        let theAttributedString = try! NSAttributedString(data: theString.data(using: String.Encoding.utf8, allowLossyConversion: false)!,options: [NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType],  documentAttributes: nil)
    
        cell.textview.attributedText =  theAttributedString
    
        cell.webview.loadHTMLString(theString, baseURL: nil)
    
        return cell
    }
    
    0 讨论(0)
  • 2020-12-04 12:17

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

    0 讨论(0)
提交回复
热议问题