1 .前端 target="_blank" 设置后无法加载页面 和 window.open(url) 无法打开新页面
原因:两者都是要在新窗口打开,判断下当前请求的targetFrame是不是MainFrame,不是则要在主动加载链接
解决办法:
- (WKWebView *)webView:(WKWebView *)webView createWebViewWithConfiguration:(WKWebViewConfiguration *)configuration forNavigationAction:(WKNavigationAction *)navigationAction windowFeatures:(WKWindowFeatures *)windowFeatures {
// 修复_blank的bug
if (!navigationAction.targetFrame.isMainFrame) {
[webView loadRequest:navigationAction.request];
}
return nil;
}
- WKWebView 加载本地资源
2.1 loadFileURL 的同级文件目录
通过allowingReadAccessToURL 参数传入需要访问的目录
NSURL * accessUrl = [NSURL fileURLWithPath:cacheDirPath()];
[self.webView loadFileURL:urlComponents.URL allowingReadAccessToURL:accessUrl];
2.2 loadHTMLString加载本地文件
- 测试baseURL 传入 [NSBundle mainBundle] 中的文件可以正常访问
- 动态创建的文件访问只能放在 NSTemporaryDirectory() 目录下才能访问(其它目录在模拟器访问没问题、真机访问不了)
NSURL * baseURL = [NSURL fileURLWithPath:NSTemporaryDirectory() isDirectory:YES];
[_web loadHTMLString:kRichEditorInitHtml baseURL:baseURL];
3.链接后边拼接url参数前端接收不到
//UIWebView经常这样拼接
[self loadUrl:[NSString stringWithFormat:@"%@?showvoice=%@",[self templatePath],[Global showvoice]]];
解决方案:使用NSURLComponents
NSURL *fileUrl = [NSURL fileURLWithPath:[self templatePath] isDirectory:NO];//此部分没有?所以没有问题,isDirectory=YES会导致多一层目录。
NSURLComponents *urlComponents = [NSURLComponents componentsWithURL:fileUrl resolvingAgainstBaseURL:NO];
[urlComponents setQueryItems:@[
[NSURLQueryItem queryItemWithName:@"showvoice" value:[Global showvoice]]
]];
NSLog(@"urlComponentsURL:%@",urlComponents.URL);
NSURL * accessUrl = [NSURL fileURLWithPath:cacheDirPath()];
[self.webView loadFileURL:urlComponents.URL allowingReadAccessToURL:accessUrl];
4.前端alter 弹出窗不弹出
解决:实现WKUIDelegate 的几个方法
// 显示一个按钮。点击后调用completionHandler回调
- (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(void))completionHandler{
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:message message:nil preferredStyle:UIAlertControllerStyleAlert];
[alertController addAction:[UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
completionHandler();
}]];
[self presentViewController:alertController animated:YES completion:nil];
}
// 显示两个按钮,通过completionHandler回调判断用户点击的确定还是取消按钮
- (void)webView:(WKWebView *)webView runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(BOOL))completionHandler{
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:message message:nil preferredStyle:UIAlertControllerStyleAlert];
[alertController addAction:[UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
completionHandler(YES);
}]];
[alertController addAction:[UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
completionHandler(NO);
}]];
[self presentViewController:alertController animated:YES completion:nil];
}
// 显示一个带有输入框和一个确定按钮的,通过completionHandler回调用户输入的内容
- (void)webView:(WKWebView *)webView runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(NSString *)defaultText initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(NSString * _Nullable))completionHandler{
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"" message:nil preferredStyle:UIAlertControllerStyleAlert];
[alertController addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) {
}];
[alertController addAction:[UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
completionHandler(alertController.textFields.lastObject.text);
}]];
[self presentViewController:alertController animated:YES completion:nil];
}