不論是UIWebView還是WKWebView對大家來說都是相當熟悉,我們一般用他們來加載網頁。
現在簡述下我的進坑心得,如果我們用固定webview高度的方式去展示網頁,不論怎樣我們都是能夠正常展示網頁的,但往往有些蛋疼的需求是要我們動態計算webview的高度,換言之就是webview高度根據內容高度自適應。一般我們用以下三種方式去處理
1、使用JS獲取
@"document.documentElement.offsetHeight"
@"document.getElementById(\"content\").offsetHeight"
NSString *tempStr = @"document.body.scrollHeight";
if (kiOS13System) {
tempStr = @"document.documentElement.scrollHeight";
}
NSString *javscript = [self.webView.URL.host isEqualToString:@"mp.weixin.qq.com"]?@"document.ge(\"page-content\").offsetHeight":tempStr;
2、使用contentSize獲取
weak_self.webView.scrollView.contentSize.height
3、使用sizeThatFits方法
[weak_self.webView sizeThatFits:CGSizeZero];
然后問題就來了,如果網頁結構是一樣的也還可以,但往往我們使用的鏈接都是五花八門的,微信公眾號的,自己的,第三方的等等,所以就出現了此起彼伏的問題。
先說結論:個人感覺第三種方案更好些,不必關心各種連接問題,能夠處理大部分問題,但是某些鏈接也會有問題。所以終極方案應該是固定高度。
頁面加載完成代理方法
// 頁面加載完成之后調用 - (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation { __weak typeof(self)weak_self = self; [self.webView evaluateJavaScript:@"document.documentElement.offsetHeight" completionHandler:^(id _Nullable result,NSError * _Nullable error) { if (_optionType == 0) { //獲取頁面高度,並重置webview的frame weak_self.webView.height = [result doubleValue]; // weak_self.tableView.tableHeaderView = weak_self.webView; [weak_self.tableView reloadData]; } }]; __block CGFloat webViewHeight; self.webView.height = webView.frame.size.height; //獲取內容實際高度(像素)@"document.getElementById(\"content\").offsetHeight;" NSString *tempStr = @"document.body.scrollHeight"; if (kiOS13System) { tempStr = @"document.documentElement.scrollHeight"; } [webView evaluateJavaScript:tempStr completionHandler:^(id _Nullable result,NSError * _Nullable error) { // 此處js字符串采用scrollHeight而不是offsetHeight是因為后者並獲取不到高度,看參考資料說是對於加載html字符串的情況下使用后者可以,但如果是和我一樣直接加載原站內容使用前者更合適 //獲取頁面高度,並重置webview的frame webViewHeight = [result doubleValue]; NSLog(@"%f",webViewHeight); dispatch_async(dispatch_get_main_queue(), ^{ if (webViewHeight != weak_self.webView.height) { webView.frame = CGRectMake(0, 0, self.view.frame.size.width, webViewHeight); [self.tableView reloadData]; } }); }]; NSLog(@"結束加載"); }
監聽webview的scrollView的contentSize屬性
- (void)addObservers{ [self.webView addObserver:self forKeyPath:@"scrollView.contentSize" options:NSKeyValueObservingOptionNew context:nil]; } - (void)removeObservers{ [self.webView removeObserver:self forKeyPath:@"scrollView.contentSize"]; }- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context{ if (object == self.webView) { if ([keyPath isEqualToString:@"scrollView.contentSize"]) { __weak typeof(self)weak_self = self; // NSString *tempStr = @"document.body.scrollHeight"; // if (kiOS13System) { // tempStr = @"document.documentElement.scrollHeight"; // } // // // NSString *javscript = [self.webView.URL.host isEqualToString:@"mp.weixin.qq.com"]?@"document.ge(\"page-content\").offsetHeight":tempStr; // [self.webView evaluateJavaScript:tempStr completionHandler:^(id _Nullable result,NSError * _Nullable error) { // //獲取頁面高度,並重置webview的frame if (_optionType == 1 || _optionType == 2) { if (add_status == 0) { add_status = 1; // weak_self.webView.height = [result doubleValue];//weak_self.webView.scrollView.contentSize.height; // weak_self.tableView.tableHeaderView = weak_self.webView; } }else{ CGSize size = [weak_self.webView sizeThatFits:CGSizeZero]; weak_self.webView.height = size.height; [weak_self.tableView setTableHeaderView:weak_self.webView]; } DDLogDebug(@"++++%@",@(weak_self.webView.height)); // }]; } } }
最終修改后大部分可以正常顯示,未見白屏,但部分公眾號文章會有廣告圖片丟失的問題
參考文章:
https://www.jianshu.com/p/6bbcc438b188
https://www.jianshu.com/p/e98e3747127c