Through research, I decided to replace the original UIWebView with WKWebView.
The first problem I encountered was that WKWebView could not be set on my favorite xib. By searching the data through the wall, the original WKWebView did not implement the initWithCoder method, and naturally found a solution:
Customize a MyWebView, inherited from WKWebView
.h
#import <WebKit/WebKit.h>
@interface MyWebView : WKWebView
@end
.m
#import "MyWebView.h"
@implementation MyWebView
- (instancetype)initWithCoder:(NSCoder *)coder
{
CGRect frame = [[UIScreen mainScreen] bounds];
WKWebViewConfiguration *configuration = [WKWebViewConfiguration new];
configuration.userContentController = [WKUserContentController new];
WKPreferences *preferences = [WKPreferences new];
preferences.javaScriptCanOpenWindowsAutomatically = YES;
configuration.preferences = preferences;
self = [super initWithFrame:frame configuration:configuration];
self.translatesAutoresizingMaskIntoConstraints = NO;
return self;
}
@end
In this way, you can set constraints in xib like UIWebView.
Import MyWebView and put it into use
#import "WebViewController.h"
#import "MyWebView.h"
//1. agency
@interface WebViewController ()<WKScriptMessageHandler, WKUIDelegate>
@property (strong, nonatomic) IBOutlet MyWebView *webView;
@end
@implementation WebViewController
- (void)viewDidLoad {
[super viewDidLoad];
UIBarButtonItem *button = [[UIBarButtonItem alloc]initWithImage:[UIImage imageNamed:@"Return"] style:UIBarButtonItemStylePlain target:self action:@selector(goBack)];
self.navigationItem.leftBarButtonItem = button;
[self.webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:self.urlString]]];
self.webView.UIDelegate = self;
//JS calls OC: set addScriptMessageHandler and name, and set < wkscriptmessagehandler > protocol and protocol method
[self.webView.configuration.userContentController addScriptMessageHandler:self name:@"callNativeKaihu"];//Open account
}
- (void)viewWillDisappear:(BOOL)animated{
[super viewWillDisappear:animated];
// Remove handlers to prevent memory leaks
[self.webView.configuration.userContentController removeScriptMessageHandlerForName:@"callNativeKaihu"];
}
- (void)goBack{
if ([self.webView canGoBack]) {
[self.webView goBack];
}else{
[self.navigationController popViewControllerAnimated:YES];
}
}
#pragma mark - WKScriptMessageHandler
//The process of OC calling method in JS
- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message
{
// Print the passed parameters. Only nsnumber, nsstring, nsdate, nsarray, nsdictionary and nsnull types are supported
NSLog(@"JS Called %@ Method, return parameters %@",message.name, message.body);
if ([message.name isEqualToString:@"callNativeKaihu"]) {
DRElectronicAccountVC *vc = [[DRElectronicAccountVC alloc]initWithNibName:@"DRElectronicAccountVC" bundle:nil];
vc.dictionary = dic[@"data"];
[self.navigationController pushViewController:vc animated:YES];
}
}
By default, WKWebView disables some jumps
- UIWebView
open www.apple.com/itunes/ Jump to the app store, make a phone call, call up the mailbox and other operations supported by UIWebView by default. - WKWebView
By default, the above behaviors are forbidden. In addition, the pop-up of js through alert() is also forbidden.
How to support it?
First, set the WKUIDelegate of WKWebView, and implement the following methods
#pragma mark - WKUIDelegate
- (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(void))completionHandler {
// The alert function in js is invalid if it is not implemented
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:message message:nil preferredStyle:UIAlertControllerStyleAlert];
[alertController addAction:[UIAlertAction actionWithTitle:@"Determine" style:UIAlertActionStyleCancel handler:^(UIAlertAction *action) {
completionHandler();
}]];
[self presentViewController:alertController animated:YES completion:^{}];
}
- (void)webView:(WKWebView *)webView runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(BOOL))completionHandler {
// The alert function in js is invalid if it is not implemented
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:message message:nil preferredStyle:UIAlertControllerStyleAlert];
[alertController addAction:[UIAlertAction actionWithTitle:@"Determine" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
completionHandler(YES);
}]];
[alertController addAction:[UIAlertAction actionWithTitle:@"cancel" style:UIAlertActionStyleCancel handler:^(UIAlertAction *action){
completionHandler(NO);
}]];
[self presentViewController:alertController animated:YES completion:^{}];
}
- (void)dealloc{
NSLog(@"observation web View release");
}