獲取高度方案1
網上最多的就是這個方法,設置 navigationDelegate
,然后在 webView:didFinishNavigation:
方法中執行一段腳本,獲取頁面高度,整體像這樣:
WKWebViewJSHeight.jpg
通過
WKWebView
執行腳本獲取 h5 內容高度的方法中,js
中對應有這么幾個高度:scrollHeight
、clientHeight
和 offsetHeight
,它們之間的區別,stackOverFlow 上一張圖很形象:
所以,我們需要獲取頁面的 scrollHeight
高度。但是這個高度有些情況下會有問題,有時候,頁面加載完成并不代表頁面中的所有內容都已經加載完畢,有些網頁的圖片使用到了懶加載的技術,只有頁面滾動到圖片的位置時,圖片才會加載出來,而在這之前,頁面上顯示的是占位圖。如果占位圖和要加載的圖片大小一致,則高度正常,內容完整顯示,萬事大吉。否則,如果占位圖比最終顯示的圖片高度要高,則最后顯示時,WKWebView
會有留白(高度被占位圖撐的過大了),反之,內容則會顯示不完整(獲取到的高度偏小)。這里插一句,WKWebView
顯示圖片時,如果圖片尺寸超過 WKWebView
的尺寸,WKWebView
會進行等比縮放進行展示。
獲取高度方案2
通過 KVO
監聽 WKWebView
的 scrollView
的 contentSize
,這樣每當頁面內容發生改變時,我們都能獲取到最新的頁面高度。
WKWebViewContentSizeHeight.jpg
如果
WKWebView
是嵌套在 UITableView
中,還需要注意在列表滑動的時候,應該避免 WKWebView
重復加載,而且高度也應該緩存起來。另外,當嵌套在 UITableView
中,WKWebView
高度更新也是比較棘手的問題。如果 WKWebView
是 UITableView
的頭部視圖,相對來說還簡單一點,可以重新設置高度,再重新設置頭部視圖即可。如果是嵌套在 cell
中而且使用的是 AutoLayout
布局,在更新 WKWebView
的高度時,就不僅需要包含 WKWebView
的 cell
更新約束,同時父視圖 UITableView
也需要進行視圖更新。常用的方法有:
- 使用
beginUpdates
和endUpdates
; - 使用
moveRowAtIndexPath:toIndexPath:
,這里前后兩個NSIndexPath
值一樣,都是包含WKWebView
的cell
的indexPath
。
不過,我在使用這兩種方法時,都偶爾會有崩潰的問題出現,而且一般都是在數據剛加載完立馬滑動視圖時出現崩潰,原因也很詭異:
[__NSArrayM objectAtIndex:]: index 6 beyond bounds [0 .. 5]
提示數組越界,網上的說法比較傾向于 UITableView
內部的錯誤,真正的原因目前未知。后來暫時的優化方案是進行高度過濾,只有在監聽到的高度大于某個值后才去更新 UITableView
,能一定程度降低崩潰,但不能避免。
WKWebView
的頁面空白問題
關于原因,這篇文章說的很清楚,從界面分析到源代碼,有理有據。在實際中使用時,大概有這么兩點需要注意:
-
WKWebView
在設置為不可滾動時,會有出現內容空白的可能,原因大致是出于性能考量。平時使用iPhone
自帶的Safari
瀏覽器,如果點擊頁面跳轉,但新內容尚未加載時,上下滑動時就可以看到有空白。 - 可以通過
WKWebView
實例調用setNeedsLayout
方法來解決這個問題。