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;
    }
}

 

希望以上能幫助更多需要幫助的人,如果有疑問,也希望大神能多多給小弟提意見和建議。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM