前言:
WKWebView 這是在iOS8.0之后增加的一個比UIWebView更加完善和強大的控件!看網上關於它的博客也是有許多的了,從各個方面總結一下這個WKWebView看網上說它主要是為了和JS做好交互產生的,我們也會相應的嘗試一下。就先從它基本的說起!
一:和UIWebView相比它的不同處
1:和JS更好的做交互,也支持H5的一些新特性
2:加載進度條(下面會演示)
3:性能高,加載變得更快更可靠
二:從加載一張網頁開始
1:使用這個WKWebView是要#import <WebKit/WebKit.h>
2:遵守協議,WKNavigationDelegate,WKUIDelegate,WKScriptMessageHandler(最后這個協議留神一下就知道視為JS准備的)
3:加載百度試一下
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
{
}
要有什么問題或者發現錯誤的地方,及時留言聯系我,立馬改正!
