1、alert textInput等UI交互解决方法
如果需要与在JS调用alert
、confirm
、prompt
函数时,通过JS原生来处理,而不是调用JS的alert
、confirm
、prompt
函数,那么需要设置UIDelegate
,在得到响应后可以将结果反馈到JS端:
1、首先设置WKUIDelegate
代理
// 与webview UI交互代理
_web_webView.UIDelegate =self;
2、然后:
与JS原生的alert
、confirm
、prompt
交互,将弹出来的实际上是我们原生的窗口,而不是JS的。在得到数据后,由原生传回到JS:
#pragma mark - WKUIDelegate
- (void)webViewDidClose:(WKWebView *)webView {
NSLog(@"%s", __FUNCTION__);
}
// 在JS端调用alert函数时,会触发此代理方法。
// JS端调用alert时所传的数据可以通过message拿到
// 在原生得到结果后,需要回调JS,是通过completionHandler回调
- (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(void))completionHandler {
NSLog(@"%s", __FUNCTION__);
UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"alert" message:@"JS调用alert" preferredStyle:UIAlertControllerStyleAlert];
[alert addAction:[UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
completionHandler();
}]];
[self presentViewController:alert animated:YES completion:NULL];
NSLog(@"%@", 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(@"%s", __FUNCTION__);
UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"confirm" message:@"JS调用confirm" preferredStyle:UIAlertControllerStyleAlert];
[alert addAction:[UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
completionHandler(YES);
}]];
[alert addAction:[UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
completionHandler(NO);
}]];
[self presentViewController:alert animated:YES completion:NULL];
NSLog(@"%@", 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];
}
2、 WKWebview与JS交互
1、WK调用JS
[_web_webView evaluateJavaScript:@"getImages()" completionHandler:^(id _Nullable script, NSError * _Nullable error) {
}];
参数1:@param 是调用的js方法,并传值
参数2:如果JavaScript 代码出错, 可以在completionHandler 进行处理.
2、2.js向oc中传值使用的时WKWebView注册WKScriptMessageHandler代理
//设置网页的配置文件
WKWebViewConfiguration * Configuration = [[WKWebViewConfiguration
alloc]init];
///添加js和wkwebview的调用
_userContentController =[[WKUserContentController alloc]init];
[_userContentController addScriptMessageHandler:self name:@"aaa"];//注册一个name为alert的js方法
Configuration.userContentController = _userContentController;
_web_webView = [[WKWebView alloc] initWithFrame:CGRectMake(0, 0, 300,500) configuration:Configuration];
#pragma mark 设置wkwebview的WKScriptMessageHandler代理方法
- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(nonnull WKScriptMessage *)message{
if ([message.name isEqualToString:@"aaa"]) {
// 打印所传过来的参数,只支持NSNumber, NSString, NSDate, NSArray,
// NSDictionary, and NSNull类型
NSLog(@"%@", message.body);
}
}
因为
[_userContentController addScriptMessageHandler:self name:@"aaa"];//注册一个name为aaa的js方法
所以要在页面销毁的时候,释放掉
///关闭web页时会释放内存
[_userContentController removeScriptMessageHandlerForName:@"aaa"];
js代码
window.webkit.messageHandlers.myName.postMessage(message);
3、使用- (nullable WKNavigation *)loadHTMLString:(NSString *)string baseURL:(nullable NSURL *)baseURL
加载HTML标签并且调取本地的JS文件
1、添加js文件到目录下,需要注意的是,js文件和图片一样属于资源文件,确保添加到Copy Bundle Resources
中
2、将js文件转为NSData添加到标签中
NSString* pathJs=[[NSBundle mainBundle]pathForResource:@"newsInfo" ofType:@"js"];
NSData *jsData=[NSData dataWithContentsOfFile:pathJs];
NSString *jsSource = [NSString stringWithFormat:@"data:js;base64,%@",[jsData base64Encoding]];
NSString *str_Header=[NSString stringWithFormat:@"<script src=\"%@\"></script>",jsSource ];
3、调用标签即可
[_web_webView loadHTMLString:[NSString stringWithFormat:@"%@%@",str_Header,str_Html] baseURL:nil];
4、添加本地图片,同本地js文件
//编码图片
- (NSString *)htmlForJPGImage:(UIImage *)image
{
NSData *imageData = UIImageJPEGRepresentation(image,1.0);
NSString *imageSource = [NSString stringWithFormat:@"data:image/jpg;base64,%@",[imageData base64Encoding]];
return [NSString stringWithFormat:@"<img src = \"%@\" />", imageSource];
}