场景

在 App 中使用UIWebView加载网页, 与原生的 UI 显示在一起,一般情况下,webView 的 内容一页是肯定不够的,换句话说,webView 的高度是不定的,那如果原生的 UI是一个 ScrollView,高度也是不定的,那放在一起的话就会有两个 ScrollView 分别滚动,而这样的体验是很差的。所以需要计算 webView 的高度,设置ScrollView可滚动,WebView 不可滚动。

尝试

我们想要的结果是将 WebView 设置为不可滚动,与原生的 UI 融合在一起,那这种情况下,我们必须得到 WebView 的内容高度,让 WebView 的高度与它所需要加载的网页的内容高度一致,才能让 WebView 将内容完全显示。一开始我是在webView加载完成的回调中去获取 webView 的 contentSize的高度。

-(void)webViewDidFinishLoad:(UIWebView *)webView{
NSLog(@"加载完成的时候的方法调用"); //WebView的高度
NSString * htmlHeight = [self stringByEvaluatingJavaScriptFromString:@"document.body.scrollHeight"];
float height = htmlHeight.floatValue;
NSLog(@"htmlHeight:%f",height);
CGRect rect = self.frame;
rect.size.height = height;
self.frame = rect;
}

用这样子的方法得到高度很有可能不是web的真实高度,如果web中有很多 图片未加载完成 的话,获取的高度将小于真实高度,那在它加载完成后,内容将显示不全。

解决

最终我是监听了 webView的 contentSize,每当contentSize的值改变时就去更改webView 的frame。

//监听webView的contentSize,每当contentSize的值改变时就去更改webView的frame
[self.scrollView addObserver:self forKeyPath:@"contentSize" options:NSKeyValueObservingOptionNew context:nil];

然后在回调方法中计算WebView的高度,改变其frame

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{
if ([keyPath isEqualToString:@"contentSize"]) {
float webViewHeight = [[self stringByEvaluatingJavaScriptFromString:@"document.body.scrollHeight"] floatValue];
// NSLog(@"webViewHeight:%f",webViewHeight);
CGRect newFrame = self.frame;
float curHeight = self.frame.size.height;
newFrame.size.height = webViewHeight;
if(newFrame.size.height!=curHeight){
self.frame = newFrame;
if(self.questionDelegate&&[self.questionDelegate respondsToSelector:@selector(questionViewDidFinishLoad:)]){
[self.questionDelegate questionViewDidFinishLoad:self];
}
}
}
}

最后,记得在页面消失viewWillDisappear或自定义的WebView的方法removeFromSuperview中remove 监听对象,否则会出现crash异常,造成应用闪退。

-(void)removeFromSuperview{
@try{
[self.scrollView removeObserver:self forKeyPath:@"contentSize" context:nil];
}@catch(NSException * e){
NSLog(@"%@",e);
}
[super removeFromSuperview];
}

动态获取UIWebView的真正高度的更多相关文章

  1. [Flex] 动态获取组件宽度和高度

    flex中我们有时并不想一开始就设置某个组件的宽度和高度,而想动态获取某个组件经填充后的width和height,但是会发现width和height均为0,这时我们可以注册一下两个事件之一来解决. i ...

  2. 获取UIWebView的内容高度

    本文转载至 http://i.cnblogs.com/EditPosts.aspx?opt=1   #pragma mark - UIWebview delegete - (void)webViewD ...

  3. JS动态获取浏览器宽度和高度

    $(window).resize(function() { var width = $(this).width(); var height = $(this).height(); });

  4. swift 动态获取label宽度或高度

    func getLabHeigh(labelStr:String,font:UIFont,width:CGFloat) -> CGFloat { let statusLabelText: NSS ...

  5. 微信小程序之动态获取元素宽高

    我以前一直以为微信小程序不能动态获取view元素的宽高.但是自从看到: wx.createSelectorQuery() 这个api接口,以前的某些问题就能得到解决了... 那么,这个api接口怎么用 ...

  6. Js动态获取iframe子页面的高度////////////////////////zzzz

    Js动态获取iframe子页面的高度   Js动态获取iframe子页面的高度总结 问题的缘由 产品有个评论列表引用的是个iframe,高度不固定于是引发这个总结. 方法1:父级页面获取子级页面的高度 ...

  7. UITableView自定义Cell中,纯代码编程动态获取高度

    在UITableView获取高度的代理方法中,经常需要根据实际的模型重新计算每个Cell的高度.直接的做法是在该代理方法中,直接根据模型来返回行高:另 [1]-(CGFloat)tableView:( ...

  8. Swift4 - 动态计算UITableView中tableHeaderView的高度 - 获取子控件高度和宽度

    核心 : /// 获取 子控件高度 func sizeHeaderToFit(view:UIView) { view.setNeedsLayout() view.layoutIfNeeded() le ...

  9. 从动态获取div高度的问题展开来看

    ps 可能篇幅比较长,请大家耐心看看 今天有人在群里问我 动态获取高度怎么获取  我就说jq中的outerHeight. height .innerHeight   原生的height clientH ...

随机推荐

  1. 7. Shell 脚本编写

    一.Shell 脚本编写 1.提示用户输入一个字符串,如果是 hello,打出 yes,并每秒输出 "hello,world",否则就输出 no,实现如下: #!/bin/bash ...

  2. ASP.NET Signalr 2.0 实现一个简单的聊天室

    学习了一下SignalR 2.0,http://www.asp.net/signalr 文章写的很详细,如果头疼英文,还可以机翻成中文,虽然不是很准确,大概还是容易看明白. 理论要结合实践,自己动手做 ...

  3. 【转】Java与C#语言级比较

    原文链接:http://www.harding.edu/fmccown/java_csharp_comparison.html Java 程序结构 C# package hello;public cl ...

  4. Sublime+Emmet

    Sublime使用Package Control安装Emmet插件: 按Ctrl+Shift+P命令板 输入install然后选择install Package,然后输入emmet找到 Emmet C ...

  5. javascript 控制input

    1.只允许输入数字     <input name="username" type="text" onkeyup="value=this.val ...

  6. Linked List Cycle (java)

    public boolean hasCycle(ListNode head) { ListNode slow=head; ListNode fast=head; if(head==null)retur ...

  7. Win7 64位系统上配置使用32位的Eclipse(转)

    Win7 64位系统上配置使用32位的Eclipse 博客分类: Eclipse eclipse  最近工作电脑换成了64位的win7系统,之前个人电脑上安装的jdk和Eclipse都是32位的.而新 ...

  8. 常用的SQL数据库语句总结

    1as 的用处 as可以对表和列取别名 在开发过程中经常遇到开始给某一个的字段去field1的名称,但后来有感觉field1字段指定不确切,于是又把此字段改成了field2,由于开始认 为field1 ...

  9. css3:border-radius圆角边框详解 (变圆 图片)

    转:http://www.kuqin.com/shuoit/20141014/342620.html border-radius:50% 今天来聊聊这个border-radius属性,radius的英 ...

  10. 【STM32】用DMA实现多路ADC通道数据采集

    今天尝试了下STM32的ADC采样,并利用DMA实现采样数据的直接搬运存储,这样就不用CPU去参与操作了. 找了不少例子参考,ADC和DMA的设置了解了个大概,并直接利用开发板来做一些实验来验证相关的 ...