效果圖.gif
實(shí)現(xiàn)功能:
將WKWebView添加進(jìn)TableViewCell.并且Cell的高度是根據(jù)WebView加載頁面自適應(yīng)的.
實(shí)現(xiàn)思路:
這個功能實(shí)現(xiàn)過程中主要遇到兩個問題.
1.什么時候發(fā)送通知給tableView,使其更新Cell高度.
因?yàn)槲覀儧]有什么屬性能夠準(zhǔn)確的獲取到webView加載頁面的進(jìn)度,所以選擇判斷document.readyState字段為complete且webView不在isLoading狀態(tài)時發(fā)送通知給tableView.
2.更新cell時webView會重新加載,從此陷入循環(huán).
選擇使用
tableView.beginUpdates()
tableView.endUpdates()
這樣只更新frame,并不重新加載數(shù)據(jù).就避免了使用relaodData()導(dǎo)致地循環(huán).
主要功能代碼:
1.Cell內(nèi)實(shí)現(xiàn)WKNavigationDelegate中didFinish方法,通過document.body.offsetHeight字段獲取加載頁面Height.通過document.readyState字段判斷頁面加載完成,發(fā)送通知.
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)
}
/// 當(dāng)確認(rèn)頁面加載完成時通知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類獲取通知,調(diào)用更新Cell高度方法
@objc private func reloadWebViewCell(_ notification: NSNotification){
let info: Int = notification.object as! Int
/// 修改cell高度
self.webViewCellHeight = info
/* 重置tableViewCell.height.
如果使用reloadData()或者reloadRow()會導(dǎo)致webView重新加載.陷入循環(huán).
使用beginUpdates只更新frame,并不重新加載
*/
tableView.beginUpdates()
tableView.endUpdates()
}
demo地址: EWWebViewCell
有問題歡迎探討.