前言:ios
WKWebView 這是在iOS8.0以後增長的一個比UIWebView更加完善和強大的控件!看網上關於它的博客也是有許多的了,從各個方面總結一下這個WKWebView看網上說它主要是爲了和JS作好交互產生的,咱們也會相應的嘗試一下。就先從它基本的提及!web
一:和UIWebView相比它的不一樣處
服務器
1:和JS更好的作交互,也支持H5的一些新特性ide
2:加載進度條(下面會演示)函數
3:性能高,加載變得更快更可靠性能
二:從加載一張網頁開始
spa
1:使用這個WKWebView是要#import <WebKit/WebKit.h>
代理
2:遵照協議,WKNavigationDelegate,WKUIDelegate,WKScriptMessageHandler(最後這個協議留神一下就知道視爲JS準備的)
code
3:加載百度試一下server
WKWebView * webviwe = [[WKWebView alloc]initWithFrame:self.view.bounds]; [webviwe loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"https://www.baidu.com"]]]; [self.view addSubview:webviwe];
三:說說加載進度條
這個是利用KVO模式寫的,WKWebView有一個 estimatedProgress 屬性,利用它來監聽加載的進度,下面的進度打印出來了,但具體的進度條就沒有寫出來,大家能夠本身寫一個 UIProgressView 放在導航欄的下面。
// estimatedProgress WKWebView 這個屬性添加觀察者 [webviwe addObserver:self forKeyPath:@"estimatedProgress" options:NSKeyValueObservingOptionNew context:nil];
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context { if (object == webviwe && [keyPath isEqualToString:@"estimatedProgress"] ) { // 這裏就不寫進度條了,把加載的進度打印出來,進度條能夠本身加上去! CGFloat newProgress = [[change objectForKey:NSKeyValueChangeNewKey] floatValue]; NSLog(@"%f",newProgress); } }
看看打印的進度信息:
2016-08-11 14:44:17.237 RaectiveCocoaTest[21054:252565] 頁面開始加載
2016-08-11 14:44:17.724 RaectiveCocoaTest[21054:252565] 0.300000
2016-08-11 14:44:17.726 RaectiveCocoaTest[21054:252565] 內容正在加載當中
2016-08-11 14:44:18.000 RaectiveCocoaTest[21054:252565] 0.719984
2016-08-11 14:44:18.196 RaectiveCocoaTest[21054:252565] 1.000000
2016-08-11 14:44:18.196 RaectiveCocoaTest[21054:252565] 頁面加載完成
四:詳細的方法使用說明以及註釋
詳解 WKNavigationDelegate 代理方法,咱們把它的代理方法使用代碼以及注意點全都寫出來,注意看下面的註釋!
#pragma mark - WKNavigationDelegate // 頁面加載開始 Provisional臨時的 -(void)webView:(WKWebView *)webView didStartProvisionalNavigation:(WKNavigation *)navigation { NSLog(@"頁面開始加載"); } // 加載內容 -(void)webView:(WKWebView *)webView didCommitNavigation:(WKNavigation *)navigation { NSLog(@"內容正在加載當中"); } // 頁面加載完成 -(void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation { NSLog(@"頁面加載完成"); } // 頁面加載失敗 -(void)webView:(WKWebView *)webView didFailProvisionalNavigation:(WKNavigation *)navigation withError:(NSError *)error { NSLog(@"頁面加載失敗"); } // 接收到服務器從新配置請求以後再執行 -(void)webView:(WKWebView *)webView didReceiveServerRedirectForProvisionalNavigation:(WKNavigation *)navigation { } // API是根據WebView對於即將跳轉的HTTP請求頭信息和相關信息來決定是否跳轉 -(void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler { NSURLRequest * request = navigationAction.request; NSLog(@"%@",request.URL.absoluteString); // 判斷請求頭是不是 https://www.baidu.com 若是是就不在請求加載跳轉 WKNavigationActionPolicy actionPolicy = WKNavigationActionPolicyAllow; if ([request.URL.absoluteString hasPrefix:@"https://www.baidu.com"]) { actionPolicy = WKNavigationActionPolicyCancel; } // 必須這樣執行,否則會崩 decisionHandler(actionPolicy); } /** * 要是容許跳轉,看下面的打印內容,注意加載的順序!和下面的方法進行比較,區分它們的不一樣之處 2016-08-11 13:55:12.628 RaectiveCocoaTest[18155:211964] https://www.baidu.com/ 2016-08-11 13:55:12.629 RaectiveCocoaTest[18155:211964] 頁面開始加載 2016-08-11 13:55:13.725 RaectiveCocoaTest[18155:211964] 內容正在加載當中 2016-08-11 13:55:14.681 RaectiveCocoaTest[18155:211964] 頁面加載完成 * */ // API是根據客戶端受到的服務器響應頭以及response相關信息來決定是否能夠跳轉 -(void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler { NSLog(@"%@",navigationResponse.response); /** * 判斷響應的數據裏面的URL是https://www.baidu.com/開頭的,要是就不讓它加載跳轉 */ WKNavigationResponsePolicy responsePolicy = WKNavigationResponsePolicyAllow; if ([navigationResponse.response.URL.absoluteString hasPrefix:@"https://www.baidu.com/"]) { responsePolicy = WKNavigationResponsePolicyCancel; } decisionHandler(responsePolicy); } /** * 響應返回的的URL包含了https://www.baidu.com/,因此頁面是不能被加載的,要是能加載就有下面的打印信息,注意和上面方法的區分對比! 2016-08-11 13:53:38.392 RaectiveCocoaTest[17961:209778] 頁面開始加載 2016-08-11 13:53:38.675 RaectiveCocoaTest[17961:209778] https://www.baidu.com/ 2016-08-11 13:53:38.678 RaectiveCocoaTest[17961:209778] 內容正在加載當中 2016-08-11 13:53:38.936 RaectiveCocoaTest[17961:209778] 頁面加載完成 */
五:說說WKUIDelegate和JS的簡單交互
先看看 WKUIDelegate裏面的代理方法都是用來作什麼的,咱們一個一個的解釋這幾個代理方法;
// 建立方法,這個就不在多說了,重點放在下面幾個 -(nullable WKWebView *)webView:(WKWebView *)webView createWebViewWithConfiguration:(WKWebViewConfiguration *)configuration forNavigationAction:(WKNavigationAction *)navigationAction windowFeatures:(WKWindowFeatures *)windowFeatures { return nil; } // ios 9 以後纔有的方法 -(void)webViewDidClose:(WKWebView *)webView { }
下面這三個方法根據方法前面的字面意思就能區分記住!
runJavaScriptAlert 方法注意點
1.在JS端調用alert函數時,會觸發此代理方法。
2.JS端調用alert時所傳的數據能夠經過message,打印message信息讀取出JS端給你的信息。
3.在原生獲得結果後,須要回調給JS,經過completionHandler 回調給JS
4.completionHandler 回調的參數和返回值都是空
/** 下面這三個方法根據前面的字面意思就能區分記住! */ // runJavaScriptAlert // 在JS端調用alert函數時,會觸發此代理方法。 // JS端調用alert時所傳的數據能夠經過message,打印message信息讀取出JS端給你的信息。 // 在原生獲得結果後,須要回調給JS,經過completionHandler 回調給JS // completionHandler 回調的參數和返回值都是空 -(void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(void))completionHandler { UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"alert"message:@"JS調用alert"preferredStyle:UIAlertControllerStyleAlert]; [alert addAction:[UIAlertAction actionWithTitle:@"肯定" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) { }]]; [self presentViewController:alert animated:YES completion:NULL]; NSLog(@"%@", message); }
runJavaScriptTextInput 注意點
1.要求用戶輸入一段文字
3.在原生輸入獲得文本內容後,經過completionHandler回調給JS
4.你們注意這個回調的completionHandler參數是字符串
// runJavaScriptTextInput // 要求用戶輸入一段文本 // 在原生輸入獲得文本內容後,經過completionHandler回調給JS 你們注意這個回調的completionHandler參數是字符串 -(void)webView:(WKWebView *)webView runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(NSString *)defaultText initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(NSString * _Nullable))completionHandler { }
runJavaScriptConfirmPane(ConfirmPane字面意思是確認框)
1.JS端調用confirm函數時,會觸發此方法
2.經過message能夠拿到JS端所傳給咱們數據
3.在iOS端顯示原生alert獲得YES/NO後,經過completionHandler回調給JS端
4.注意這個completionHandler回調的參數是BOOL類型的
-(void)webView:(WKWebView *)webView runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(BOOL))completionHandler { }
要有什麼問題或者發現錯誤的地方,及時留言聯繫我,立馬改正!