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
中
42C13F62-A6AB-4C69-AB55-BA5652F39579.png
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];
}