最近碰到的项目需要加载html页面.本以为只是调用WKWebView加载即可.但还是碰到不少坑.做个笔记
1.后台给的html页面没有适配手机端.页面经常超出屏幕.按以下代码进行适配.即可使页面适合屏幕.
var web : WKWebView?
let con = WKWebViewConfiguration.init()
con.preferences.minimumFontSize = 8.0
let js = "var meta = document.createElement('meta'); meta.setAttribute('name', 'viewport'); meta.setAttribute('content', 'width=device-width'); document.getElementsByTagName('head')[0].appendChild(meta);"
let wkUS = WKUserScript.init(source: js, injectionTime: WKUserScriptInjectionTime.atDocumentEnd, forMainFrameOnly: true)
let wkUC = WKUserContentController()
wkUC.addUserScript(wkUS)
con.userContentController = wkUC
web = WKWebView.init(frame: CGRect(x: 0, y: 0, width: xh_ScreenWidth, height: 0), configuration: con)
2.项目需求获取html页面中的图片.当用户点击时跳出页面展示大图.
var imgList = [String]()// 图片地址列表
func getImgList() {
let jsGetImages =
"function getImages(){" +
"var objs = document.getElementsByTagName(\"img\");" +
"var imgScr = '';" +
"for(var i=0;i<objs.length;i++){" +
"imgScr = imgScr + objs[i].src + '+';" +
"};" +
"return imgScr;" +
"};"
web.evaluateJavaScript(jsGetImages, completionHandler: nil)
// 执行获取图片地址列表方法
weak var wself = self
web.evaluateJavaScript("getImages()") { (urlResult, error) in
if urlResult == nil { return }
let resStr : String = urlResult as! String
let subList = resStr.split(separator: "+")
for (_,subStr) in subList.enumerated() {
let str = String(subStr).zh_imgPath()
wself?.imgList.append(str)
wself?.fileList.append(XHFileModel(URLPath: str))
}
}
let jsClickImage =
"function registerImageClickAction(){" +
"var imgs=document.getElementsByTagName('img');" +
"var length=imgs.length;" +
"for(var i=0;i<length;i++){" +
"img=imgs[i];" +
"img.οnclick=function(){" +
"window.location.href='image-preview:'+this.src}" +
"}" +
"}"
web.evaluateJavaScript(jsClickImage, completionHandler: nil)
web.evaluateJavaScript("registerImageClickAction()", completionHandler: nil)
}
// 之后在WKWebView代理完成加载回调中调用 注入上面的代码就可以拿到图片地址列表
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
wself?.getImgList()
}
// 最后在以下方法中加入代码.
func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
let requestString = navigationAction.request.url?.absoluteString
if (requestString?.hasPrefix("image-preview"))!{
// 在这里拿到点击的图片url地址和获取点击第几张图片.然后做处理.
let imgUrl = NSString.init(string: requestString!).substring(from: "image-preview:".count )
let index = imgList.index(of: imgUrl) ?? 0
// 可以考虑根据响应链拿到最近的控制器去push页面. 也可以用闭包回调给控制器再做处理.
}
decisionHandler(.allow) //一定要加上这句话
}
3.在cell中加载html页面.并适配高度.我的做法是在WKWebView加载完后拿到其高度做为cell的高度并用闭包回调给tableView刷新.也可以从响应链拿到tableView然后刷新.
注:如果加载的html页面没有适配手机屏幕.我们也没有做处理的话.拿到的高度很可能是错的.这就需要按第1点做一下适配或者让相关人员做一下手机端适配.
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
let webH = webView.scrollView.contentSize.height
self.callBack?(webH)
}
另外.因为html加载的不确定性.其高度可能是100也可能是1000导致tableView页面刷新时estimatedRowHeight我们无法给出一个比较接近的值.所以就在以下代理方法中做处理
func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
if 如果判断当前cell是放置网页的cell {
return webH// 返回从网页cell中回调过来的高度
}
return UITableView.automaticDimension
}