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 = @"<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);
            }
        }
    }
    
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 每次在商场看玩具,嘉小妹都会说妈妈,给我买这个吧!给我买那个吧!然后老母亲会指着包装盒上的字念:仅限三岁以上儿童。...
    真水无香_d868阅读 1,868评论 0 1
  • 我的朋友苏苏,本来是办理经济案件的律师,最近受好友委托,接了一起离婚的案子。男女主人公没有闹到对簿公堂的地步,双方...
    迷你欧阅读 3,677评论 1 4
  • 最近工作上从云端回到平地,所能做的很少,只有等待。 多了很多时间,对有更多的时间自己把握看书和学习也挺开心。 每次...
    无名氏_noname阅读 1,553评论 0 0
  • 眼前境地所相期,每欲吟来总得时。 长使梦幽思无限,况因杯浅醉何迟, 应惜少年情若在,独怜秋鬓性难移。 来年莫问风光...
    雪窗_武立之阅读 1,634评论 0 1
  • 關心則亂 言多必失 惦記不止~慾也 前進便後悔 退後又不甘
    林素兮阅读 1,738评论 3 3

友情链接更多精彩内容