完整項目github地址: https://github.com/MisterZhouZhou/WKWebViewUseing
iOS8開始,蘋果重構了UIWebVIew,給我們帶來了WKWebView,WKWebView具有以下優勢: 1、在性能、穩定性、功能方面有很大提升; 2、允許javaScript的Nitro庫加載并使用(UIWebView中限制); 3、支持了更多的HTML5特性; 4、高達60fps的滾動刷新率以及內置手勢; 5、將UIWebViewDelegate與UIWebView重構成了14類與3個協議
一、WKWebView Framework
WKWebView的14個類與3個協議: WKBackForwardList: 之前訪問過的 web 頁面的列表,可以通過后退和前進動作來訪問到。
WKBackForwardListItem: webview 中后退列表里的某一個網頁。
WKFrameInfo: 包含一個網頁的布局信息。
WKNavigation: 包含一個網頁的加載進度信息。
WKNavigationAction: 包含可能讓網頁導航變化的信息,用于判斷是否做出導航變化。
WKNavigationResponse: 包含可能讓網頁導航變化的返回內容信息,用于判斷是否做出導航變化。
WKPReferences: 概括一個 webview 的偏好設置。
WKProcessPool: 表示一個 web 內容加載池。
WKUserContentController: 提供使用 Javascript post 信息和注射 script 的方法。
WKScriptMessage: 包含網頁發出的信息。
WKUserScript: 表示可以被網頁接受的用戶腳本。
WKWebViewConfiguration: 初始化 webview 的設置。
WKWindowFeatures: 指定加載新網頁時的窗口屬性。
WKWebsiteDataStore: 包含網頁數據存儲和查找。
WKNavigationDelegate: 提供了追蹤主窗口網頁加載過程和判斷主窗口和子窗口是否進行頁面加載新頁面的相關方法。
WKUIDelegate: 提供用原生控件顯示網頁的方法回調。
WKScriptMessageHandler: 提供從網頁中收消息的回調方法。
二、WKWebView中的三個代理方法
1、WKNavigationDelegate
該代理提供的方法,可以用來追蹤加載過程(頁面開始加載、加載完成、加載失敗)、決定是否執行跳轉。
// 頁面開始加載時調用- (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(WKNavigation *)navigation;// 當內容開始返回時調用- (void)webView:(WKWebView *)webView didCommitNavigation:(WKNavigation *)navigation;// 頁面加載完成之后調用- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation;// 頁面加載失敗時調用- (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(WKNavigation *)navigation;頁面跳轉的代理方法有三種,分為(收到跳轉與決定是否跳轉兩種)// 接收到服務器跳轉請求之后調用- (void)webView:(WKWebView *)webView didReceiveServerRedirectForProvisionalNavigation:(WKNavigation *)navigation;// 在收到響應后,決定是否跳轉- (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler;// 在發送請求之前,決定是否跳轉- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler;2 、WKUIDelegate
創建一個新的WKWebView
// 創建一個新的WebView- (WKWebView *)webView:(WKWebView *)webView createWebViewWithConfiguration:(WKWebViewConfiguration *)configuration forNavigationAction:(WKNavigationAction *)navigationAction windowFeatures:(WKWindowFeatures *)windowFeatures;剩下三個代理方法全都是與界面彈出提示框相關的,針對于web界面的三種提示框(警告框、確認框、輸入框)分別對應三種代理方法。
// 界面彈出警告框- (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(void (^)())completionHandler;// 界面彈出確認框- (void)webView:(WKWebView *)webView runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(BOOL result))completionHandler;// 界面彈出輸入框- (void)webView:(WKWebView *)webView runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(nullable NSString *)defaultText initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(NSString * __nullable result))completionHandler;3、 WKScriptMessageHandler
這個協議中包含一個必須實現的方法,這個方法是native與web端交互的關鍵,它可以直接將接收到的JS腳本轉為OC或Swift對象。
// 從web界面中接收到一個腳本時調用- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message;三、WKWebView使用
1、設置配置信息
WKWebViewConfiguration *config = [[WKWebViewConfiguration alloc] init]; //設置顯示字體的大小 config.preferences.minimumFontSize = 16;2、創建WKWebView
self.wkWebView = [[WKWebView alloc] initWithFrame:CGRectMake(0, 40, self.view.bounds.size.width, self.view.bounds.size.height/3*2) configuration:config]; self.wkWebView.navigationDelegate = self; self.wkWebView.UIDelegate = self; self.wkWebView.backgroundColor = [UIColor lightGrayColor]; [self.view addSubview:self.wkWebView];3、加載文件
NSString *filePath = [[NSBundle mainBundle] pathForResource:@"index" ofType:@"html"]; NSURL *url = [NSURL fileURLWithPath:filePath]; NSURLRequest *request = [NSURLRequest requestWithURL:url]; [self.wkWebView loadRequest:request];4、監聽JS調用
WKUserContentController *userCC = config.userContentController; //JS調用OC 添加處理腳本 [userCC addScriptMessageHandler:self name:@"showJSToOC1"]; [userCC addScriptMessageHandler:self name:@"showJSToOC2"];5、調用JS
[self.wkWebView evaluateJavaScript:@"showLog()" completionHandler:nil];6、處理請求跳轉
// 在發送請求之前,決定是否跳轉- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler{ NSLog(@"%s",__func__); decisionHandler(WKNavigationActionPolicyAllow);}7、處理彈框(alert默認是不顯示的,想顯示彈框需要設置以下delegate方法,并執行回調方法)
// 界面彈出警告框- (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(void))completionHandler{ UIAlertController *alertController = [UIAlertController alertControllerWithTitle:message message:nil preferredStyle:UIAlertControllerStyleAlert]; [alertController addAction:[UIAlertAction actionWithTitle:@"確定" style:UIAlertActionStyleCancel handler:^(UIAlertAction *action) { completionHandler(); }]]; [self presentViewController:alertController animated:YES completion:^{}];}// 界面彈出確認框- (void)webView:(WKWebView *)webView runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(BOOL result))completionHandler{ UIAlertController *alertController = [UIAlertController alertControllerWithTitle:message message:nil preferredStyle:UIAlertControllerStyleAlert]; [alertController addAction:[UIAlertAction actionWithTitle:@"確定" style:UIAlertActionStyleCancel handler:^(UIAlertAction *action) { completionHandler(YES); }]]; [self presentViewController:alertController animated:YES completion:^{}];}// 界面彈出輸入框- (void)webView:(WKWebView *)webView runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(nullable NSString *)defaultText initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(NSString * __nullable result))completionHandler{ UIAlertController *alertController = [UIAlertController alertControllerWithTitle:prompt message:@"" preferredStyle:UIAlertControllerStyleAlert]; [alertController addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) { textField.text = defaultText; }]; [alertController addAction:([UIAlertAction actionWithTitle:@"完成" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) { completionHandler(alertController.textFields[0].text?:@""); }])]; [self presentViewController:alertController animated:YES completion:nil];}8、釋放監聽方法
-(void)dealloc{ [[self.wkWebView configuration].userContentController removeScriptMessageHandlerForName:@"showJSToOC1"]; [[self.wkWebView configuration].userContentController removeScriptMessageHandlerForName:@"showJSToOC2"];}效果圖: 
新聞熱點
疑難解答