iOS项目之WKWebView替换UIWebView相关

        在网上已经有了许多关于UIWebView替换为WKWebView的文章,所以在这里就不在多说替换的细节了,不会的可以在网上搜搜。

        下面是我在项目中遇到的问题:

问题一:在UIWebView中,网页显示(包括图片显示)比例正常,替换为WKWebView后,比例显示不正常

解决方案:直接上代码

        /* 在创建WKWebView的时候,配置环境中添加下面的js语句,可以使界面自适应屏幕 */
        // 自适应屏幕宽度js
        NSString *jSString = @"var meta = document.createElement('meta'); meta.setAttribute('name', 'viewport'); meta.setAttribute('content', 'width=device-width'); document.getElementsByTagName('head')[0].appendChild(meta);";
        
        WKUserScript *wkUserScript = [[WKUserScript alloc] initWithSource:jSString injectionTime:WKUserScriptInjectionTimeAtDocumentEnd forMainFrameOnly:YES];

        // 自定义配置,一般用于js调用oc方法(oc拦截URL中的数据做自定义操作)
        WKUserContentController *userContentController = [[WKUserContentController alloc] init];

        [userContentController addUserScript:wkUserScript];    

        解决图片显示比例的代码在我的另外一篇文章中写到过,这里就不再写了。

问题二:将webView添加到cell的contentView中,UIWebView创建的界面能够展示完整,而WKWebView创建的界面只能够展示一部分

分析:此时出现的白屏问题,详细分析可以去看看这位大神写的简书(WKWebView刷新机制小探):http://www.jianshu.com/p/1d739e2e7ed2,地址已附上。

解决方案:在cell的contentView中添加自定义的scrollView,然后再将WKWebView创建的webView添加到这个scrollView中,就能解决此类白屏问题。

部分代码附上:

@interface WebCell ()<WKNavigationDelegate, WKUIDelegate, WKScriptMessageHandler>

@property(nonatomic, weak) UIScrollView *webScrollView;

@property(nonatomic, weak) WKWebView *webView;

@end

@implementation WebCell

- (UIScrollView *)webScrollView
{
    if (!_webScrollView) {
        UIScrollView *sv = [[UIScrollView alloc] init];
        [self.contentView addSubview:sv];
        _webScrollView = sv;
    }
    return _webScrollView;
}

- (WKWebView *)webView
{
    if (!_webView) {
        // 配置环境
        WKWebViewConfiguration *configuration = [[WKWebViewConfiguration alloc] init];
        // 自适应屏幕宽度js
        NSString *jSString = @"var meta = document.createElement('meta'); meta.setAttribute('name', 'viewport'); meta.setAttribute('content', 'width=device-width'); document.getElementsByTagName('head')[0].appendChild(meta);";
        WKUserScript *wkUserScript = [[WKUserScript alloc] initWithSource:jSString injectionTime:WKUserScriptInjectionTimeAtDocumentEnd forMainFrameOnly:YES];
        // 允许视频播放
        if (iOS_Version(9.0)) {
            configuration.allowsAirPlayForMediaPlayback = YES;
        }
        // 允许在线播放
        configuration.allowsInlineMediaPlayback = YES;
        // 允许与网页交互
        configuration.selectionGranularity = YES;
        // 内容处理池
        configuration.processPool = [[WKProcessPool alloc] init];
        // 自定义配置,一般用于js调用oc方法(oc拦截URL中的数据做自定义操作)
        WKUserContentController *userContentController = [[WKUserContentController alloc] init];
        // 添加消息处理,注意:self指代的对象需要遵守WKScriptMessageHandler协议,结束时需要移除
        [userContentController addScriptMessageHandler:self name:@"Handle"];
        [userContentController addUserScript:wkUserScript];
        // 是否支持记忆读取
        configuration.suppressesIncrementalRendering = YES;
        // 允许用户更改网页的设置
        configuration.userContentController = userContentController;
        // 创建wk
        WKWebView *wv = [[WKWebView alloc] initWithFrame:CGRectZero configuration:configuration];
        // 设置背景色
        wv.backgroundColor = [UIColor clearColor];
        wv.opaque = NO;
        // 设置代理
        wv.navigationDelegate = self;
        wv.UIDelegate = self;
        // 网页内容禁用滑动
        wv.scrollView.scrollEnabled = NO;
        
        // kvo添加进度监控
//        [wv addObserver:self forKeyPath:NSStringFromSelector(@selector(estimatedProgress)) options:0 context:nil];
        
        // 开启手势触摸
        wv.allowsBackForwardNavigationGestures = YES;
        // 自适应
        [wv sizeToFit];
        
        [self.webScrollView addSubview:wv];
        _webView = wv;
    }
    return _webView;
}

#pragma mark - <设置数据>
- (void)setModel:(Model *)model
{
    _model = model;
    
    // 手动改变图片适配问题,拼接html代码后,再加载html代码
        NSString *myStr = [NSString stringWithFormat:@"<head><style>img{max-width:%f !important;}</style></head>", SCREEN_WIDTH - 20];
        NSString *str = [NSString stringWithFormat:@"%@%@",myStr, model.htmlStr];
        [self.webView loadHTMLString:str baseURL:nil];
}

#pragma mark - <界面布局>
- (void)layoutSubviews
{
    [super layoutSubviews];
    
    [self.webView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.bottom.left.right.mas_equalTo(self.contentView);
    }];
}

#pragma mark - <WKNavigationDelegate>
- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation
{
    [webView evaluateJavaScript:@"document.body.scrollHeight" completionHandler:^(id _Nullable response, NSError * _Nullable error) {
        // 获取webView的高度
        CGFloat webViewHeight = [response floatValue];
       // 设置自定义scrollView的frame
        self.webScrollView.frame = CGRectMake(0, 0, SCREEN_WIDTH, webViewHeight);
        // 通过代理方法,刷新表格高度
        if ([self.delegate respondsToSelector:@selector(webViewWithChangeHeight:)]) {
            [self.delegate webViewWithChangeHeight:webViewHeight];
        }
    }];
}

- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message
{}

- (void)dealloc
{
    [self.webView.configuration.userContentController removeScriptMessageHandlerForName:@"Handle"];
}

@end

 问题三:webView中有捏合手势,往往在项目中我们不需要这个手势,则看下面的js代码

- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation
{
    // 禁用网页捏合手势
    NSString *injectionJSString = @"var script = document.createElement('meta');"
    "script.name = 'viewport';"
    "script.content=\"width=device-width, initial-scale=1.0,maximum-scale=1.0, minimum-scale=1.0, user-scalable=no\";"
    "document.getElementsByTagName('head')[0].appendChild(script);";
    [webView evaluateJavaScript:injectionJSString completionHandler:nil];
}

问题四:如果在webView中,需要点击网页中的图片查看大图时,则看下面的js代码

- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation
{
    //这里是js,主要目的实现对url的获取
    static  NSString * const jsGetImages =
    @"function getImages(){\
    var objs = document.getElementsByTagName(\"img\");\
    var imgScr = '';\
    for(var i=0;i<objs.length;i++){\
    imgScr = imgScr + objs[i].src + '+';\
    };\
    return imgScr;\
    };";
    
    [webView evaluateJavaScript:jsGetImages completionHandler:nil];
    
    // 执行js中方法获取图片
    [webView evaluateJavaScript:@"getImages()" completionHandler:^(id _Nullable response, NSError * _Nullable error) {
        NSString *urlResurlt = [NSString stringWithFormat:@"%@", response];
        _mUrlArray = [NSMutableArray arrayWithArray:[urlResurlt componentsSeparatedByString:@"+"]];
        if (_mUrlArray.count >= 2) {
            [_mUrlArray removeLastObject];
        }
        //urlResurlt 就是获取到得所有图片的url的拼接;_mUrlArray就是所有Url的数组
    }];

    //添加图片可点击js
    static  NSString * const jsImageClick =
    @"function registerImageClickAction(){\
    var imgs=document.getElementsByTagName('img');\
    var length=imgs.length;\
    for(var i=0;i<length;i++){\
    img=imgs[i];\
    img.onclick=function(){\
    window.location.href='image-preview:'+this.src}\
    }\
    }";
    
    [webView evaluateJavaScript:jsImageClick completionHandler:nil];
    
    [webView evaluateJavaScript:@"registerImageClickAction()" completionHandler:nil];
}

- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler
{
    decisionHandler(WKNavigationActionPolicyAllow);
    
    //预览图片
    if ([navigationAction.request.URL.scheme isEqualToString:@"image-preview"]) {
        NSString* path = [navigationAction.request.URL.absoluteString substringFromIndex:[@"image-preview:" length]];
        path = [path stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
        //path 就是被点击图片的url
        
        // 在这里获取网页中的图片数组,进行展示

        return;
    }
    
    if ([navigationAction.request.URL.scheme isEqualToString:@""]) {
//        NSLog(@"%@", navigationAction.request.URL);//在这里可以获得事件
        return;
    }
}

 

希望以上能帮助更多需要帮助的人,如果有疑问,也希望大神能多多给小弟提意见和建议。

 

posted @ 2017-02-24 16:17  兔.小白  阅读(4069)  评论(0编辑  收藏  举报