在網上已經有了許多關於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; } }
希望以上能幫助更多需要幫助的人,如果有疑問,也希望大神能多多給小弟提意見和建議。