实现功能:
将WKWebView添加进TableViewCell.并且Cell的高度是根据WebView加载页面自适应的.
实现思路:
这个功能实现过程中主要遇到两个问题.
1.什么时候发送通知给tableView,使其更新Cell高度.
因为我们没有什么属性能够准确的获取到webView加载页面的进度,所以选择判断document.readyState字段为complete且webView不在isLoading状态时发送通知给tableView.
2.更新cell时webView会重新加载,从此陷入循环.
选择使用
tableView.beginUpdates()
tableView.endUpdates()
这样只更新frame,并不重新加载数据.就避免了使用relaodData()导致地循环.
主要功能代码:
1.Cell内实现WKNavigationDelegate中didFinish方法,通过document.body.offsetHeight字段获取加载页面Height.通过document.readyState字段判断页面加载完成,发送通知.
extension EWWebViewTableViewCell: WKNavigationDelegate {
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
/// 获取完成页面的Height
webView.evaluateJavaScript("document.body.offsetHeight") { (obj, error) in
guard let height = obj as? Int else { return }
self.webView.frame.size.height = CGFloat(height)
}
/// 当确认页面加载完成时通知TableView修改Cell高度
self.webView.evaluateJavaScript("document.readyState") { (obj, complete) in
if obj as? String == "complete" && !self.webView.isLoading{
NotificationCenter.default.post(name: NSNotification.Name(rawValue: "webViewHeightCallBack"), object: self.webView.frame.size.height)
}
}
}
}
2.tableView类获取通知,调用更新Cell高度方法
@objc private func reloadWebViewCell(_ notification: NSNotification){
let info: Int = notification.object as! Int
/// 修改cell高度
self.webViewCellHeight = info
/* 重置tableViewCell.height.
如果使用reloadData()或者reloadRow()会导致webView重新加载.陷入循环.
使用beginUpdates只更新frame,并不重新加载
*/
tableView.beginUpdates()
tableView.endUpdates()
}
demo地址: EWWebViewCell
有问题欢迎探讨.
网友评论