我有一个UITableViewCell,里面有一个UIWebView。 我从服务器加载的数据有几个注释,其中包含丰富的HTML内容(文本,图像,链接等)。由于单元格包含UIWebView,因此我必须等到整个内容加载完毕才能获取tableViewCell的高度并进行更新。
我遇到的问题是,当我向下滚动时,单元格将被更新,并且整个视图会出现抖动和闪烁。基本上,我正在寻找一种预加载Web视图的方法以预先获取其高度。而且,这种抽动只会发生在所有单元格都加载了内容之前,因为我是在本地存储每个单元格的高度。
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委托方法
//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)
}
代表高度的委托方法
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()
}
另一个问题是,如果Web视图包含沉重的图像,则每次将单元出队时,整个Web视图都会在重新加载时闪烁,从而导致不良的体验。
Here's the example of webview with image reloading
一段时间后,由于缓存了Webview,图像问题得以解决,但是体验仍然很差。
有没有办法解决这些问题?
答案 0 :(得分:3)
您可以创建一个Web视图数组并将其存储在视图控制器中,预加载其内容并在加载时显示某种微调器动画。完成所有网络视图的加载后,您应该能够获得各种网络视图的内容高度。
您可能必须修改单元格,以便它们可以接收Web视图作为参数;您将整个网络视图传递到单元格,该单元格将其添加为内容的子视图。
在单元格prepareForReuse()函数中,确保删除所有添加的Web视图。您不希望在重复使用单元格时保留以前的Web视图。