不论是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

02-13 11:31