iOS 获取webview高度小结
不论是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