zoukankan      html  css  js  c++  java
  • 动态获取UIWebView的真正高度

    场景

    在 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];
    }
  • 相关阅读:
    Spark5
    Spark4
    Spark3
    冲刺周期二--站立会议01
    团队第一阶段绩效考核
    各个小组对“躲避小球”游戏的评价
    软件项目第一个Sprint评论
    丹佛机场行李处理系统
    冲刺周期一--站立会议07
    冲刺周期一--站立会议06
  • 原文地址:https://www.cnblogs.com/hacjy/p/5141623.html
Copyright © 2011-2022 走看看