WKWebView的基本使用

一、WKWebView的基本使用

  1. 初始化方法
    - (instancetype)initWithFrame:(CGRect)frame configuration:(WKWebViewConfiguration *)configuration
  2. 簡單介紹一下configuration,WKWebViewConfiguration里面有個userContentController。可通過它為webview注入javaScript代碼。并且可以添加監聽javaScript的回調。
    (1)初始化configurationWKWebViewConfiguration *configuration = [[WKWebViewConfiguration alloc]init];
    (2)獲取javaScript代碼,我把javaScript代碼寫在了一個文件中NSString *jsStr = [NSString stringWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"WKWebViewJS" ofType:@"js"] encoding:NSUTF8StringEncoding error:nil];
    (3)初始化script對象
    /*@abstract 初始script對象
     @param source javaScript代碼
     @param injectionTime 注入javaScript代碼的時機
     @param forMainFrameOnly 是不是僅為MainFrame注入
     */
    WKUserScript *userScript = [[WKUserScript alloc]initWithSource:jsStr injectionTime:WKUserScriptInjectionTimeAtDocumentStart forMainFrameOnly:NO];

(4)添加script對象[configuration.userContentController addUserScript:userScript];
(5)添加scriptMessage回調
[configuration.userContentController addScriptMessageHandler:self name:@"imageClick"]; [configuration.userContentController addScriptMessageHandler:self name:@"popToPreviousVC"];
若添加過回調之后,在結束調用這個方法window.webkit.messageHandlers.<handleName>.postMessage(<messageBody>) 系統會調用這個方法- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message

  1. WKWebView 執行javaScript代碼
    self.webview evaluateJavaScript:@"changeFontSize(12)" completionHandler:^(id _Nullable result, NSError * _Nullable error) { }];
  2. WKWebView的一些簡單屬性的介紹
backForwardList            瀏覽歷史
title                      網頁標題             支持KVO
URL                        正在顯示的URL        支持KVO
loading                    是否正在加載          支持KVO
estimatedProgress          加載進度             支持KVO
canGoBack  canGoForward    能否后退 前進         支持KVO
reload                     重新加載
stopLoading                停止加載
allowsBackForwardNavigationGestures  是否允許側滑返回上一頁

5、WKWebView的加載方法跟UIWebView基本一樣

- (nullable WKNavigation *)loadRequest:(NSURLRequest *)request;
- (nullable WKNavigation *)loadHTMLString:(NSString *)string baseURL:(nullable NSURL *)baseURL;
- (nullable WKNavigation *)loadData:(NSData *)data MIMEType:(NSString *)MIMEType characterEncodingName:(NSString *)characterEncodingName baseURL:(NSURL *)baseURL;

二 WKWebViewUIDelegate

//當需要打開一個新窗口的時候的調用,如a標簽的target='_blank',需要返回一個新的Webview
- (nullable WKWebView *)webView:(WKWebView *)webView createWebViewWithConfiguration:(WKWebViewConfiguration *)configuration forNavigationAction:(WKNavigationAction *)navigationAction windowFeatures:(WKWindowFeatures *)windowFeatures
以下三個類似alert的代理,一定要調用completionHandler(),這個回調,告訴webview結果
//webview上需要彈出alert的時候調用此方法,如果不實現此方法,則webview的alert是顯示不出來,alert類似于只有確定按鈕的UIAlertView
- (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(void))completionHandler
//webview上需要彈出confirm的時候調用此方法,如果不實現此方法,則webview的confirm是顯示不出來,confirm類似于有確定按鈕和取消按鈕的UIAlertView
- (void)webView:(WKWebView *)webView runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(BOOL result))completionHandler
 webview上需要彈出prompt的時候調用此方法,如果不實現此方法,則webview的prompt是顯示不出來,prompt類似于帶一個textField的UIAlertView。defaultText相當于textField的placeholed
- (void)webView:(WKWebView *)webView runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(nullable NSString *)defaultText initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(NSString * __nullable result))completionHandler
//window.close() 的時候調用
- (void)webViewDidClose:(WKWebView *)webView

三 WKWebViewNavigationDelegate

//決定是否允許發起這個請求
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler
//在webview有響應之后,再次決定是否允許這個請求
- (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandle
//webview開始加載的時候調用
- (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(null_unspecified WKNavigation *)navigation
//webview內容已經加載結束,但是上面的某些資源比如圖片加載之前調用
- (void)webView:(WKWebView *)webView didCommitNavigation:(null_unspecified WKNavigation *)navigation
//webview加載結束的時候調用
- (void)webView:(WKWebView *)webView didCommitNavigation:(null_unspecified WKNavigation *)navigation
//webview加載失敗的時候調用
- (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(null_unspecified WKNavigation *)navigation withError:(NSError *)error
//webview在commit過程中失敗的時候調用,例如在didCommitNavigation這個代理方法中調用webview的stopLoading方法
- (void)webView:(WKWebView *)webView didFailNavigation:(null_unspecified WKNavigation *)navigation withError:(NSError *)error

四 WKScriptMessageHandler

//收到JavaScript回調的時候調用
- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message

五 接下來用一下做個小demo。

功能如下:
1、點擊按鈕可以控制webView上的字體的大小和顏色
2、點擊webView上的返回,能pop到上一個VC
3、點擊webView圖片,彈出alert告訴我彈出的是第幾張圖片,和圖片的大小和位置以及所有的圖片的地址
4、驗證代理方法
效果如下:

1.gif

(1)首先為webview注入JS代碼,JS代碼里主要實現的是:當window加載之后,為img標簽添加click事件,定義改變字體顏色和大小的函數

   WKWebViewConfiguration *configuration = [[WKWebViewConfiguration alloc]init];
   NSString *jsStr = [NSString stringWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"WKWebViewJS" ofType:@"js"] encoding:NSUTF8StringEncoding error:nil];
   WKUserScript *userScript = [[WKUserScript alloc]initWithSource:jsStr injectionTime:WKUserScriptInjectionTimeAtDocumentStart forMainFrameOnly:NO];
   [configuration.userContentController addUserScript:userScript];
   [configuration.userContentController addScriptMessageHandler:self name:@"imageClick"];
   [configuration.userContentController addScriptMessageHandler:self name:@"popToPreviousVC"];

(2)調用JS代碼,實現改變字體顏色和大小

- (void)runJavaAcript:(UIButton *)button{
    if (button.tag == 0) {
        [self.webview evaluateJavaScript:@"changeTextColor('#f00')" completionHandler:^(id _Nullable result, NSError * _Nullable error) {
        }];
    }else if (button.tag == 1){
        [self.webview evaluateJavaScript:@"changeTextColor('#666')" completionHandler:^(id _Nullable result, NSError * _Nullable error) {
        }];
    }else if (button.tag == 2){
        [self.webview evaluateJavaScript:@"changeFontSize(38)" completionHandler:^(id _Nullable result, NSError * _Nullable error) {
        }];
    }else if (button.tag == 3){
        [self.webview evaluateJavaScript:@"changeFontSize(12)" completionHandler:^(id _Nullable result, NSError * _Nullable error) {
        }];
    }
}

(3)點擊webview上的返回按鈕pop到上一個VC
1)在html中的定義

//返回標簽的定義
<button onclick="popToPreviousVC()">返回</button>
//函數實現
function popToPreviousVC(){
    webkit.messageHandlers.popToPreviousVC.postMessage(true);
}

2)webview收到回調的處理

- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message{
    if ([message.name isEqualToString:@"imageClick"]) {
        NSInteger current = [message.body[@"current"] integerValue];
        UIAlertView *alert = [[UIAlertView alloc]initWithTitle:[NSString stringWithFormat:@"你點擊了第%ld張圖片,該圖片的坐標是%@",(long)current,message.body[@"rect"]] message:[NSString stringWithFormat:@"圖片的地址分別是:%@",message.body[@"srcs"]] delegate:nil cancelButtonTitle:nil otherButtonTitles:@"OK", nil];
        [alert show];
    }else if([message.name isEqualToString:@"popToPreviousVC"]){
        [self.navigationController popViewControllerAnimated:YES];
    }
}

要想接收到回調,一定要先在先添加回調,而且添加的名字一定要和發送的名字一致
[configuration.userContentController addScriptMessageHandler:self name:@"popToPreviousVC"];

(4)點擊webView圖片,彈出alert告訴我彈出的是第幾張圖片,和圖片的大小和位置以及所有的圖片的地址,回調的信息如上,下面展示js代碼

function initImageClick(obj,index) {
    obj.onclick = function imgOnclick() {
        //獲取image的位置
        var rect = obj.getBoundingClientRect();
        //獲取所有的img標簽
        var imgs = document.getElementsByTagName('img');
        var srcs = new Array();
        for(var i in imgs){
            //判斷img的src是否為未定義,加入srcs數組
            if(imgs[i].src != undefined)
            srcs.push(imgs[i].src);
        }
        //由于OC不識別rect這個對象,在這把rect轉成了符合CGRect格式的字符串
        var message = {'rect':'{{'+rect.left+', '+rect.top+'}, {'+rect.width+', '+rect.height+'}}}'};
        //為message這個js對象的屬性賦值
        message.current = index;
        message.srcs = srcs;
        //發送消息
        webkit.messageHandlers.imageClick.postMessage(message);
    }
}

代理方法的驗證具體看demo

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 之前一直是使用UIWebView與后臺交互,這些天剛接觸WKWebView,感覺速度要比UIWebVeiw快很多,...
    大_龍_蝦閱讀 1,860評論 0 0
  • 發現 關注 消息 iOS 第三方庫、插件、知名博客總結 作者大灰狼的小綿羊哥哥關注 2017.06.26 09:4...
    肇東周閱讀 12,180評論 4 61
  • 這是一個難題,是在一生里 多年的心事都已沉入海底 我站在岸堤,望著天際 不知道,那會不會隨著潮汐 來到這里 這多年...
    二莎子閱讀 251評論 0 0
  • 我沒有參加挑戰杯,幫忙修改進了省賽的結題論文;沒有參加演說比賽,觀看了大量精彩的演說談話節目;沒有談戀愛,經常有朋...
    簡二閱讀 306評論 0 1
  • 1. 人,其實不需要太多的東西,只要健康的活著,真誠的愛著,也不失為一種富有。 2. 想不開,就不想,得不到,就不...
    指尖傳奇閱讀 530評論 0 0