1、首先引入?yún)f(xié)議
<WKUIDelegate,WKNavigationDelegate,WKScriptMessageHandler>
@interface ViewController ()
@property (nonatomic, strong) WKWebView *webView;
@end@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
//配置文件
WKWebViewConfiguration *config = [[WKWebViewConfiguration alloc] init];
//注冊js方法
[config.userContentController addScriptMessageHandler:self name:@"getToken"];
//根據(jù)配置文件,創(chuàng)建webview
self.webView = [[WKWebView alloc] initWithFrame:[UIScreen mainScreen].bounds configuration:config];
//ui代理
self.webView.UIDelegate = self;
//導航欄代理
self.webView.navigationDelegate = self;
[self.webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"https://www.baidu.com"]]];
[self.view addSubview:self.webView];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation {
}
//在這個方法js調(diào)用原生
- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message {
}
2、js調(diào)用oc方法
①當js想傳一些數(shù)據(jù)給oc時,他們會調(diào)用一下方法來發(fā)送,<getToken>,getToken是方法名<"name">是傳的參數(shù)
window.webkit.messageHandlers.<getToken>.postMessage(<“name”>)
②oc通過以下方法,注冊JS的MessageHandler
[config.userContentController addScriptMessageHandler:self name:@"getToken"];
③在如下方法中進行邏輯處理
- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message {
if ([message.name isEqualToString:@"getToken"]) {
}
}
④為防止內(nèi)存泄露,需要在dealloc方法中要移除
- (void)dealloc {
[[_webView configuration].userContentController removeScriptMessageHandlerForName:@"方法名"];
}
三、oc調(diào)用js
如下MiniProgramCallBack是原生調(diào)用js的方法,括號()內(nèi)的是原生傳給js的參數(shù)
NSString *jsStr = [NSString stringWithFormat:@"ReturnToken('%@')", @"token=123456"];
[webView evaluateJavaScript:jsStr completionHandler:nil]
四、添加進度條
①初始化進度條
- (UIProgressView *)progressView{
if (!_progressView) {
_progressView = [[UIProgressView alloc] initWithFrame:CGRectMake(0, 0, SCREEN_WIDTH, 2)];
_progressView.backgroundColor = [UIColor blueColor];
_progressView.transform = CGAffineTransformMakeScale(1.0f, 1.5f); _progressView.progressTintColor = [UIColor app_color_yellow_eab201];
[self.view addSubview:self.progressView];
}
return _progressView;
}
②
給ViewController中添加Observer
[self.webView addObserver:self forKeyPath:@"estimatedProgress" options:NSKeyValueObservingOptionNew context:nil];
在dealloc方法刪除Observer
[self.webView removeObserver:self forKeyPath:@"estimatedProgress"];
③在observeValueForKeyPath中添加對progressView的進度顯示操作
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{
if ([keyPath isEqualToString:@"estimatedProgress"]) {
self.progressView.progress = self.webView.estimatedProgress;
if (self.progressView.progress == 1) {
WeakSelfDeclare
[UIView animateWithDuration:0.25f delay:0.3f options:UIViewAnimationOptionCurveEaseOut animations:^ { weakSelf.progressView.transform = CGAffineTransformMakeScale(1.0f, 1.4f);
} completion:^(BOOL finished) {
weakSelf.progressView.hidden = YES;
}];
}
}
}
④顯示progressView
- (void)webView:(WKWebView*)webView didStartProvisionalNavigation:(WKNavigation*)navigation{
self.progressView.hidden =NO;
self.progressView.transform =CGAffineTransformMakeScale(1.0f,1.5f);
[self.view bringSubviewToFront:self.progressView];
}
⑤隱藏progressView
- (void)webView:(WKWebView*)webView didFinishNavigation:(WKNavigation*)navigation {
self.progressView.hidden =YES;
}
- (void)webView:(WKWebView*)webView didFailNavigation:(WKNavigation*)navigation withError:(NSError*)error {if(error.code==NSURLErrorCancelled) {
[selfwebView:webView didFinishNavigation:navigation]; }else{self.progressView.hidden =YES;
}
}
- (void)webView:(WKWebView*)webView didFailProvisionalNavigation:(WKNavigation*)navigation withError:(NSError*)error {
self.progressView.hidden =YES;
[self.navigationItem setTitleWithCustomLabel:@"加載失敗"];
}
五、彈框
WKWebView中的WKUIDelegate實現(xiàn)UI彈出框的一些處理(警告面板、確認面板、輸入框)。
- 在JS端調(diào)用alert函數(shù)時,會觸發(fā)此代理方法。JS端調(diào)用alert時所傳的數(shù)據(jù)可以通過message拿到。在原生得到結(jié)果后,需要回調(diào)JS,是通過completionHandler回調(diào)。
- (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(void))completionHandler {
NSLog(@"message = %@",message);
}
- JS端調(diào)用confirm函數(shù)時,會觸發(fā)此方法,通過message可以拿到JS端所傳的數(shù)據(jù),在iOS端顯示原生alert得到Y(jié)ES/NO后,通過completionHandler回調(diào)給JS端 ```
- (void)webView:(WKWebView *)webView runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(BOOL result))completionHandler {
NSLog(@"message = %@",message);
}
- JS端調(diào)用prompt函數(shù)時,會觸發(fā)此方法,要求輸入一段文本,在原生輸入得到文本內(nèi)容后,通過completionHandler回調(diào)給JS ```
- (void)webView:(WKWebView *)webView runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(nullable NSString *)defaultText initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(NSString * __nullable result))completionHandler { NSLog(@"%s", __FUNCTION__);
NSLog(@"%@", prompt);
UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"textinput" message:@"JS調(diào)用輸入框" preferredStyle:UIAlertControllerStyleAlert];
[alert addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) { textField.textColor = [UIColor redColor];
}];
[alert addAction:[UIAlertAction actionWithTitle:@"確定" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) { completionHandler(
[[alert.textFields lastObject] text]);
}]
];
[self presentViewController:alert animated:YES completion:NULL]; }