iOS开发 | UIWebView&WKWebView高

作者: Lol刀妹 | 来源:发表于2017-02-11 23:48 被阅读3207次
    少女时代-林允儿

    需求还原:

    如图所示:
    整个页面分为上下两部分:上部分是普通的view,下部分是一个webview,加载H5文本。需求是这两部分要同时滚动。

    上部分是普通view下部分是webview.png

    思路

    把上下两部分放在一个scrollView上,设置webview不可滚动并且让webview高度自适应内容(webView.height = webView.scrollView.contentSize.height),再调整scrollView的contentSize。

    实现方法

    在webview的代理方法webViewDidFinishLoad:中做相应处理即可:

    
    - (void)webViewDidFinishLoad:(UIWebView *)webView{
        // webView加载完成,让webView高度自适应内容
        self.contentWebView.height = self.contentWebView.scrollView.contentSize.height;
        self.contentScrollView.contentSize = CGSizeMake(screenWidth, self.contentWebView.maxY);
    }
    
    

    存在的问题

    没过多久,测试妹纸就反馈有时webview只显示了部分内容。我就纳闷了,我的思路和代码都是完美无bug的,不应该有问题啊但是后面测试妹纸不停的向我反馈这个问题,我知道,肯定是自己的代码有问题了。把代码反复看了几遍,最终定位到webViewDidFinishLoad :这个方法上。于是上网查询,终于知道了原因:
    我想当然的认为webViewDidFinishLoad :回调之时就是webview加载完成之日(有多少人被坑过)。实际上并不是,这里就不做过多讨论了,详情自己上网查询(网页重定向)。只需要记住:webViewDidFinishLoad :回调的时候并不能说明webview加载完成

    解决问题

    知道问题所在后解决问题就简单了:需要找准webview加载完成的那个点。结合网上前辈提供的方法,我给UIWebView写了一个category,用来判断webview是不是真正的完成了加载。代码如下:

    /** 判断webView是否完全加载完数据 */
    - (BOOL)isFinishLoading{
        NSString *readyState = [self stringByEvaluatingJavaScriptFromString:@"document.readyState"];
        BOOL complete = [readyState isEqualToString:@"complete"];
        if (complete && !self.isLoading) {
            return YES;
        }else{
            return NO;
        }
    }
    

    这就在原来的基础上多了一个判断:

    - (void)webViewDidFinishLoad:(UIWebView *)webView{
        // webView加载完成,让webView高度自适应内容
        if ([webView isFinishLoading] == YES) {
            self.contentWebView.height = self.contentWebView.scrollView.contentSize.height;
            self.contentScrollView.contentSize = CGSizeMake(screenWidth, self.contentWebView.maxY);
        }
    }
    

    这样,webview高度自适应内容就完成了。

    优化

    虽然功能是完成了,但是却不怎么完美:我们初始化webview的时候会给webview设置一个frame,如果webview的height设置低了,加载数据期间将只能显示部分内容;如果webview高度设置太大,加载数据期间下方又是一片空白。如果能动态持续的改变webview的高度,那这个问题也就解决了。方法就是:实时监听webview的scrollView的contentSize的变化,然后调整webview的高度。代码如下:

        // webview高度自适应内容
        [RACObserve(self.contentWebView.scrollView, contentSize) subscribeNext:^(id x) {
            self.contentWebView.height = self.contentWebView.scrollView.contentSize.height;
            self.contentScrollView.contentSize = CGSizeMake(screenWidth, self.contentWebView.maxY);
        }];
    

    这是最简单同时也是最完美的实现方法(用这个方法就不需要再在webview的代理方法里做处理了)。什么你没用RAC?好吧那你就用传统的KVO咯。建议没学RAC的去了解一下,有时候对于简化代码还是很有帮助的。

    至此,UIWebView高度自适应内容以及持续自适应就完美实现了。讲了这么多其实核心就是监听webView.scrollView.contentSize的变化然后调整webView的高度

    WKWebView处理方式一样

    使用KVO:

    #pragma mark - KVO
    - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context {
        self.webView.height = self.webView.scrollView.contentSize.height;
    }
    

    使用WKWebView时你可能会遇到的问题

    1. 字体相比UIWebView更小了

    解决方法:https://stackoverflow.com/questions/45998220/the-font-looks-like-smaller-in-wkwebview-than-in-uiwebview/46000849#46000849

    2.底部大片空白

    解决方法:稍微延迟一下

    #pragma mark - KVO
    - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context {
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
            self.webView.height = self.webView.scrollView.contentSize.height;
        });
    }
    

    相关文章

      网友评论

      • edb493d9a752:第一次加载的时候 走了监听 但是更新url的时候不走监听 怎么办
      • manofit:最近用WKwebview,出现底部空白,甩给h5那边了,老夫已经无能为力了
        Lol刀妹:@manofit 恩恩,那就好
        manofit:@无夜之星辰 这个我倒没注意,不过现在那边已经解决了,其实就是那边高度没有自适应
        Lol刀妹:你用WKWebView后,是不是字体变小了?
      • 51aa90fc67ff:看了这么多方法 ,这个最有效!:joy: :joy:
      • 专心致志的程序员:妹夫,不错学习了,待会去试试:smile:
      • a632073b5a6a:大神,有没得demo啊,最近弄这个玩意弄了两天了
        Lol刀妹:@lyq226809 你用的UIWebView还是WKWebView?如果是WKWebView这几种方法都不能保证一定有效,我也没找到有效的方法。UIWebView直接观察scroll view 的contentSize就可以了
      • 伦敦乡下的小作家:妹夫,写得不错,项目正好有类似的需求
        Lol刀妹:妹儿我都没看到:sleepy:
      • 春暖花已开:妹夫,写得不错,项目正好有类似的需求
        Lol刀妹:@人民重重 在网上找了很久,没找到合适的,后面我灵光一闪,想到了kvo,完美解决问题。还有,你都还没把你妹介绍给我:smirk:

      本文标题:iOS开发 | UIWebView&WKWebView高

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