美文网首页
iOS获取WebView的高度

iOS获取WebView的高度

作者: HF_K | 来源:发表于2020-03-06 19:22 被阅读0次

    前言

    需要显示一个资讯详情页面,涉及到webView和自定义控件的结合,页面上半部分是webView,下面是一个tableViewwebView必须显示完整的网页信息,这时候就需要计算出webView的高度。

    iOS获取WebView的高度_1.gif

    方法

    网上介绍的方法很多,大概分为两种。

    方法1:webView的代理中去获取webView的高度

    //WKWebView
    - (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation{
        if (self.hud) {
            [self.hud hideAnimated:YES];
        }
        [webView evaluateJavaScript:@"document.body.scrollHeight"
                  completionHandler:^(id result, NSError *_Nullable error) {
            [self.webView mas_updateConstraints:^(MASConstraintMaker *make) {
                make.height.equalTo([result floatValue]);
            }];
            self.tableView.tableHeaderView = self.headerView;
        }];
    }
    

    方法2:通过KVO监听webView的高度,然后更新高度。

    //WKWebView
    [self.webView.scrollView addObserver:self forKeyPath:@"contentSize" options:NSKeyValueObservingOptionOld | NSKeyValueObservingOptionNew context:nil];
    

    //监听高度变化
    - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{
        if ([keyPath isEqualToString:@"contentSize"]) {
          
        }
    }
    

    问题

    用上面方法1方法2方法监听高度,然后更新高度偶尔会发现高度不准。因为webView中包含图片等资源它们加载过程中需要一定时间,只有当它们完全加载完成以后,获取的高度才是真正的高度。

    解决办法

    方法1:通过代理KVO监听webView高度变化

    1. 监听webView的高度变化。

       //WKWebView
       [self.webView.scrollView addObserver:self forKeyPath:@"contentSize" options:NSKeyValueObservingOptionOld | NSKeyValueObservingOptionNew context:nil];
       [self.webView makeConstraints:^(MASConstraintMaker *make) {
           make.top.equalTo(timeLab.mas_bottom).offset(10);
           make.left.right.equalTo(titleLab);
           make.height.equalTo(100);
       }];
       
       //代理中更新contentHeight变量变化
       - (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation{
           if (self.hud) {
               [self.hud hideAnimated:YES];
           }
           [webView evaluateJavaScript:@"document.body.scrollHeight"
                     completionHandler:^(id result, NSError *_Nullable error) {
               [self.webView mas_updateConstraints:^(MASConstraintMaker *make) {
                   make.height.equalTo([result floatValue]);
               }];
               self.tableView.tableHeaderView = self.headerView;
           }];
       }
      
       //KVO监听webView高度变化从而刷新UI
       - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{
           if ([keyPath isEqualToString:@"contentSize"]) {
               CGFloat height = self.webView.scrollView.contentSize.height;
               NSLog(@"-----------height= %.1f",height);
               [self.webView mas_updateConstraints:^(MASConstraintMaker *make) {
                   make.height.equalTo(height);
               }];
               self.tableView.tableHeaderView = self.headerView;
           }
       }
      
      
       //移除KVO监听   
       -(void)dealloc{
          [self.webView.scrollView removeObserver:self forKeyPath:@"contentSize"];
       }
      

    通过上述方法基本可以实现功能。

    方法2:通过和H5进行JS交互从而实现监听
    H5那边一定要在文字跟图片都加载完成再去获取高度,因为图片是异步加载的,否则获取到的高度不准。在H5完成加载内容后通过JS告诉App然后App实现刷新

      //(1)进行配置控制器---跟H5交互用
    WKWebViewConfiguration *configuration = [[WKWebViewConfiguration alloc] init];
    //实例化对象
    configuration.userContentController = [WKUserContentController new];
     WKWebView * webView = [[WKWebView alloc]initWithFrame:CGRectMake(0, 0, SCREEN_WIDTH, 10)];
    
    //(2)与JS交互的注册,JS调用OC方法--注册前先z初始化上面方法
        [webView.configuration.userContentController addScriptMessageHandler:self name:@"getWkWebViewHeight"];
    
     //(3)加载url
      [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:self.urlString]]];
    
    
    //(4)HTML内容从后台请求完成后传给H5--js,等待H5加载完页面给iOS回调高度【注意:H5那边一定要在图片也加载完后才返回高度,不然返回的高度不准】
        NSString * HtmlStr = @"<p>HTML内容</p>
    ";
      NSDictionary *dicData = @{@"content": HtmlStr};
        //字典转JSON
        NSString * jsonStr = [NSDictionary dictionaryToJson:dicData];
        NSString *js = [NSString stringWithFormat:@"window.dataInfo = %@", jsonStr];
        WKUserScript *script = [[WKUserScript alloc] initWithSource:js injectionTime:(WKUserScriptInjectionTimeAtDocumentStart) forMainFrameOnly:YES];
        [[self configuration].userContentController addUserScript:script];
    
    
    //得到js传输回来的数据
    //WKScriptMessageHandler协议方法
    - (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message {
        //code
    //    NSDictionary *dictData = [NSDictionary jsonToDictionaryWithJsonString:message.body];
        
        if ([message.name isEqualToString:@"getWkWebViewHeight"]) {
         
            NSLog(@"获取新闻高度:%@",message.body);
            if ([self.typeString isEqual:@"新闻详情"]) {
                NSString * strHeight = [NSString stringWithFormat:@"%@",message.body];
                CGFloat heightWeb = [strHeight doubleValue];//得到网页高度
                //网页高度回调
                if (self.WebviewHeight) {
                    self.WebviewHeight(heightWeb);
                }
            }
        }
        
    }

    相关文章

      网友评论

          本文标题:iOS获取WebView的高度

          本文链接:https://www.haomeiwen.com/subject/vcvgrhtx.html