iOS WKWebView 基本使用

weixin_33866037發表於2016-11-29

現在大部分的app只支援iOS8以上的系統了,在接入H5時可以只管最新的WKWebView了。

WKWebView的優勢

  1. 效能高,穩定性好,佔用的記憶體比較小,
  2. 支援JS互動
  3. 支援HTML5 新特性
  4. 可以新增進度條(然並卵,不好用,還是習慣第三方的)。
  5. 支援內建手勢,
  6. 據說高達60fps的重新整理頻率(不卡)

接下來直接進入主題

  • 首先需要匯入庫檔案
    #import <WebKit/WebKit.h>
  • 同時繼承2個代理事件
    <WKNavigationDelegate,WKUIDelegate>
  • 建立WKWebView
    self.webView = [[WKWebView alloc] initWithFrame:self.view.frame];
    [self.webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://192.168.99.81:8020/goldenWater/watersupermarketList.html"]]];
    self.webView.navigationDelegate = self;
    self.webView.UIDelegate = self;
    //開了支援滑動返回
    self.webView.allowsBackForwardNavigationGestures = YES;
    [self.view addSubview:self.webView];
  • WKUIDelegate代理事件
// 頁面開始載入時呼叫
-(void)webView:(WKWebView *)webView didStartProvisionalNavigation:(WKNavigation *)navigation{
    
}
// 當內容開始返回時呼叫
- (void)webView:(WKWebView *)webView didCommitNavigation:(WKNavigation *)navigation{
    
}
// 頁面載入完成之後呼叫
- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation{//這裡修改導航欄的標題,動態改變
    self.title = webView.title;
}
// 頁面載入失敗時呼叫
- (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{
    
    DLog(@"%@",webView);
    DLog(@"%@",navigationResponse);
    
    WKNavigationResponsePolicy actionPolicy = WKNavigationResponsePolicyAllow;
    //這句是必須加上的,不然會異常
    decisionHandler(actionPolicy);
    
}
// 在傳送請求之前,決定是否跳轉
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler{
    
    self.title = webView.title;
    
    WKNavigationActionPolicy actionPolicy = WKNavigationActionPolicyAllow;
    
    
    if (navigationAction.navigationType==WKNavigationTypeBackForward) {//判斷是返回型別
        
        //同時設定返回按鈕和關閉按鈕為導航欄左邊的按鈕 這裡可以監聽左滑返回事件,仿微信新增關閉按鈕。
        self.navigationItem.leftBarButtonItems = @[self.backBtn, self.closeBtn];
        //可以在這裡找到指定的歷史頁面做跳轉
//        if (webView.backForwardList.backList.count>0) {                                  //得到棧裡面的list
//            DLog(@"%@",webView.backForwardList.backList);
//            DLog(@"%@",webView.backForwardList.currentItem);
//            WKBackForwardListItem * item = webView.backForwardList.currentItem;          //得到現在載入的list
//            for (WKBackForwardListItem * backItem in webView.backForwardList.backList) { //迴圈遍歷,得到你想退出到
//                //新增判斷條件
//                [webView goToBackForwardListItem:[webView.backForwardList.backList firstObject]];
//            }
//        }
    }
    //這句是必須加上的,不然會異常
    decisionHandler(actionPolicy);
}
  • WKUIDelegate代理事件,主要實現與js的互動
 //顯示一個JS的Alert(與JS互動)
- (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(void))completionHandler{
    DLog(@"彈窗alert");
    DLog(@"%@",message);
    DLog(@"%@",frame);
    [self.view makeToast:message];
    completionHandler();
}

//彈出一個輸入框(與JS互動的)
- (void)webView:(WKWebView *)webView runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(nullable NSString *)defaultText initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(NSString * __nullable result))completionHandler{
    DLog(@"彈窗輸入框");
    DLog(@"%@",prompt);
    DLog(@"%@",defaultText);
    DLog(@"%@",frame);
    
    UIAlertController *alert = [UIAlertController alertControllerWithTitle:prompt message:defaultText preferredStyle:UIAlertControllerStyleAlert];
    UIAlertAction *a1 = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
        //這裡必須執行不然頁面會載入不出來
        completionHandler(@"");
    }];
    UIAlertAction *a2 = [UIAlertAction actionWithTitle:@"確認" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
        DLog(@"%@",
             [alert.textFields firstObject].text);
        completionHandler([alert.textFields firstObject].text);
    }];
    [alert addAction:a1];
    [alert addAction:a2];
    [alert addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) {
        DLog(@"%@",textField.text);
    }];
    [self presentViewController:alert animated:YES completion:nil];
}

//顯示一個確認框(JS的)
- (void)webView:(WKWebView *)webView runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(BOOL result))completionHandler{
    DLog(@"彈窗確認框");
    DLog(@"%@",message);
    DLog(@"%@",frame);
    

    UIAlertController *alertController = [UIAlertController alertControllerWithTitle:message message:nil preferredStyle:UIAlertControllerStyleAlert];
    UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
        completionHandler(NO);
    }];
    UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"確認" style:UIAlertActionStyleDestructive handler:^(UIAlertAction * _Nonnull action) {
        completionHandler(YES);
    }];
    [alertController addAction:cancelAction];
    [alertController addAction:okAction];
    [self presentViewController:alertController animated:YES completion:nil];
}

重寫左上角返回按鈕,這個很重要,使用者體驗影響很大

-(void)backNative{
    //判斷是否有上一層H5頁面
    if ([self.webView canGoBack]) {
        //如果有則返回
        [self.webView goBack];
        //同時設定返回按鈕和關閉按鈕為導航欄左邊的按鈕
        self.navigationItem.leftBarButtonItems = @[self.backBtn, self.closeBtn];
    } else {
        [self closeNative];
    }
}
如果需要顯示網頁載入進度,移步我之前的文章

iOS WKWebView顯示網頁載入進度條

到這裡基本上就實現了內嵌H5的載入,大家可以放http://m.jd.com試試事件效果

1642379-f5201bd36bd60851.gif
示例圖

【原創出品 未經授權 禁止轉載】
【歡迎微友分享轉發 禁止公號等未經授權的轉載】

相關文章