獲取高度方案1
網(wǎng)上最多的就是這個(gè)方法,設(shè)置 navigationDelegate,然后在 webView:didFinishNavigation: 方法中執(zhí)行一段腳本,獲取頁面高度,整體像這樣:

通過
WKWebView 執(zhí)行腳本獲取 h5 內(nèi)容高度的方法中,js 中對(duì)應(yīng)有這么幾個(gè)高度:scrollHeight、clientHeight 和 offsetHeight,它們之間的區(qū)別,stackOverFlow 上一張圖很形象:


所以,我們需要獲取頁面的 scrollHeight 高度。但是這個(gè)高度有些情況下會(huì)有問題,有時(shí)候,頁面加載完成并不代表頁面中的所有內(nèi)容都已經(jīng)加載完畢,有些網(wǎng)頁的圖片使用到了懶加載的技術(shù),只有頁面滾動(dòng)到圖片的位置時(shí),圖片才會(huì)加載出來,而在這之前,頁面上顯示的是占位圖。如果占位圖和要加載的圖片大小一致,則高度正常,內(nèi)容完整顯示,萬事大吉。否則,如果占位圖比最終顯示的圖片高度要高,則最后顯示時(shí),WKWebView 會(huì)有留白(高度被占位圖撐的過大了),反之,內(nèi)容則會(huì)顯示不完整(獲取到的高度偏小)。這里插一句,WKWebView 顯示圖片時(shí),如果圖片尺寸超過 WKWebView 的尺寸,WKWebView 會(huì)進(jìn)行等比縮放進(jìn)行展示。
獲取高度方案2
通過 KVO 監(jiān)聽 WKWebView 的 scrollView 的 contentSize,這樣每當(dāng)頁面內(nèi)容發(fā)生改變時(shí),我們都能獲取到最新的頁面高度。

如果
WKWebView 是嵌套在 UITableView 中,還需要注意在列表滑動(dòng)的時(shí)候,應(yīng)該避免 WKWebView 重復(fù)加載,而且高度也應(yīng)該緩存起來。另外,當(dāng)嵌套在 UITableView 中,WKWebView 高度更新也是比較棘手的問題。如果 WKWebView 是 UITableView 的頭部視圖,相對(duì)來說還簡單一點(diǎn),可以重新設(shè)置高度,再重新設(shè)置頭部視圖即可。如果是嵌套在 cell 中而且使用的是 AutoLayout 布局,在更新 WKWebView 的高度時(shí),就不僅需要包含 WKWebView 的 cell 更新約束,同時(shí)父視圖 UITableView 也需要進(jìn)行視圖更新。常用的方法有:
- 使用
beginUpdates和endUpdates; - 使用
moveRowAtIndexPath:toIndexPath:,這里前后兩個(gè)NSIndexPath值一樣,都是包含WKWebView的cell的indexPath。
不過,我在使用這兩種方法時(shí),都偶爾會(huì)有崩潰的問題出現(xiàn),而且一般都是在數(shù)據(jù)剛加載完立馬滑動(dòng)視圖時(shí)出現(xiàn)崩潰,原因也很詭異:
[__NSArrayM objectAtIndex:]: index 6 beyond bounds [0 .. 5]
提示數(shù)組越界,網(wǎng)上的說法比較傾向于 UITableView 內(nèi)部的錯(cuò)誤,真正的原因目前未知。后來暫時(shí)的優(yōu)化方案是進(jìn)行高度過濾,只有在監(jiān)聽到的高度大于某個(gè)值后才去更新 UITableView,能一定程度降低崩潰,但不能避免。
WKWebView 的頁面空白問題
關(guān)于原因,這篇文章說的很清楚,從界面分析到源代碼,有理有據(jù)。在實(shí)際中使用時(shí),大概有這么兩點(diǎn)需要注意:
-
WKWebView在設(shè)置為不可滾動(dòng)時(shí),會(huì)有出現(xiàn)內(nèi)容空白的可能,原因大致是出于性能考量。平時(shí)使用iPhone自帶的Safari瀏覽器,如果點(diǎn)擊頁面跳轉(zhuǎn),但新內(nèi)容尚未加載時(shí),上下滑動(dòng)時(shí)就可以看到有空白。 - 可以通過
WKWebView實(shí)例調(diào)用setNeedsLayout方法來解決這個(gè)問題。