ios - 如何优化在多个 TableViewCells 内的 UIWebView 中加载大量不同的 HTML 内容?

标签 ios swift uitableview uiwebview

我有一个 UITableViewCell,里面有一个 UIWebView。 我从服务器加载的数据有几个包含丰富 HTML 内容(文本、图像、链接等)的评论。由于单元格包含 UIWebView,我必须等到整个内容加载完毕才能获取 tableViewCell 的高度并更新它。

我遇到的问题是,当我向下滚动时,单元格会更新,整个 View 会抖动和闪烁。基本上,我正在寻找一种方法来预加载 webviews 以预先获得它们的高度。此外,由于我在本地存储每个单元格的高度,所以这种抖动只会在所有单元格都加载内容后才会发生。

Here's an example of the jittery experience.

cellForRowIndex代码

open func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(indexPath: indexPath) as LiMessageDetailTableViewCell
    cell.delegate = self
    cell.cellModel = LiMessageDetailTableViewCellModel(data: messageObject.originalMessage, index: indexPath)
    cell.heightOfWebView = messageObject.contentHeightsOriginalMessage[indexPath.row]
    if messageObject.contentHeightsOriginalMessage[indexPath.row] != 0.0 {
        cell.updateHeightConstrain()
    }
    return cell
}

TableViewCell 中的 WebView 委托(delegate)方法

 //MARK:- WEBVIEW DELEGATE
    func webViewDidFinishLoad(_ webView: UIWebView) {
     //This section resizes the webview according to the new content loaded.
        var mframe = webView.frame
        mframe.size.height = 1
        webView.frame = mframe
        let fittingSize = webView.sizeThatFits(.zero)
        mframe.size = fittingSize
        webView.frame = mframe
    /**
    I found that javascript gives a more accurate height when images are
    included since they take more time loading than the normal content and 
    hence sizeThatFits does not always return proper result.
    **/
        let heightInString = webView.stringByEvaluatingJavaScript(from: "document.body.scrollHeight") ?? ""
        guard let heightInFloat = Float(heightInString) else { return }
        guard let index = cellModel?.indexPath else {return}
        constrainHeightOfWebView.constant = fittingSize.height
        guard let cellType = cellModel?.messageType  else { return }
        delegate?.updateHeight(index: index, newHeight: CGFloat(heightInFloat), cellType: cellType)
    }

更新高度的委托(delegate)方法

func updateHeight(index: IndexPath, newHeight: CGFloat, cellType: LiMessageType) {
    switch cellType {
    case .originalMessage:
        if msgObj.contentHeightsOriginalMessage[index.row] != 0.0 && msgObj.contentHeightsOriginalMessage[index.row] == newHeight {
            return
        }
        msgObj.contentHeightsOriginalMessage[index.row] = newHeight
   .....
    }
    self.tableView.beginUpdates()
    self.tableView.endUpdates()
}

另一个问题是,如果 webview 包含大量图像,则整个 webview 会闪烁,因为它会在每次 cell 出队时重新加载,从而导致糟糕的体验。

Here's the example of webview with image reloading

随着 webview 被缓存,图像问题会在一段时间后自行解决,但仍然是一种糟糕的体验。

有没有办法解决这些问题?

最佳答案

您可以创建一个 WebView 数组并将其存储在您的 View Controller 中,预加载它们的内容并在它们加载时显示某种微调器动画。所有 WebView 加载完成后,您应该能够获取各种 WebView 的内容高度。

您可能必须修改您的单元格,以便它们可以接收 WebView 作为参数;您将整个 WebView 传递给单元格,该单元格会将其添加为内容的 subview 。

在单元格 prepareForReuse() 函数中,确保删除任何添加的 Web View 。因为您不希望在重复使用单元格时保留以前的 Web View 。

关于ios - 如何优化在多个 TableViewCells 内的 UIWebView 中加载大量不同的 HTML 内容?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51791476/

相关文章:

ios - 创建通用脂肪框架 lipo : can't create temporary output file

Swift:如何将字符串转换为字典

swift - 如何根据 didSelectRowatIndexPath 位置显示数组中的项目?

objective-c - 从其他类添加对象到 NSMutableArray

iphone - 如何使用 iOS 5.1 打开首选项/设置?

ios - 带有 iOS 9.2 错误的 Xcode 7.1(找不到开发者磁盘镜像)

ios - 应用程序不会在设备上显示第一个 View (也不会崩溃),但在模拟器中可以完美运行。还为设备加载不同的图标

swift - 快速将 UIImage 更改为数组或矩阵

ios - 在 UITableView 中列出目录的内容

ios - 检测单元格内 UILabel 上的点击