iOS获取WebView的高度


前言

需要显示一个资讯详情页面,涉及到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 = @"

HTML内容

"; 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的高度)