1、首先引入协议
<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"];
//根据配置文件,创建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调用原生
- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message {
}
2、js调用oc方法
①当js想传一些数据给oc时,他们会调用一下方法来发送,<getToken>,getToken是方法名<"name">是传的参数
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"]) {
}
}
④为防止内存泄露,需要在dealloc方法中要移除
- (void)dealloc {
[[_webView configuration].userContentController removeScriptMessageHandlerForName:@"方法名"];
}
三、oc调用js
如下MiniProgramCallBack
是原生调用js的方法,括号()
内的是原生传给js的参数
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实现UI弹出框的一些处理(警告面板、确认面板、输入框)。
- 在JS端调用alert函数时,会触发此代理方法。JS端调用alert时所传的数据可以通过message拿到。在原生得到结果后,需要回调JS,是通过completionHandler回调。
- (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(void))completionHandler {
NSLog(@"message = %@",message);
}
- JS端调用confirm函数时,会触发此方法,通过message可以拿到JS端所传的数据,在iOS端显示原生alert得到YES/NO后,通过completionHandler回调给JS端 ```
- (void)webView:(WKWebView *)webView runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(BOOL result))completionHandler {
NSLog(@"message = %@",message);
}
- JS端调用prompt函数时,会触发此方法,要求输入一段文本,在原生输入得到文本内容后,通过completionHandler回调给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调用输入框" 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]; }
网友评论