通過調(diào)研,我決定使用WKWebView替換原來的UIWebView。
遇到的第一個問題就是WKWebView無法在我喜愛的xib上設(shè)置禽翼,通過翻墻搜索資料溪北,原來WKWebView沒有實現(xiàn)initWithCoder方法劳翰,自然也就找到了解決辦法:
自定義一個MyWebView生均,繼承自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
這樣就可以像UIWebView一樣在xib設(shè)置約束了垫卤。
導(dǎo)入MyWebView评抚,投入使用
#import "WebViewController.h"
#import "MyWebView.h"
//1. 代理
@interface WebViewController ()<WKScriptMessageHandler, WKUIDelegate>
@property (strong, nonatomic) IBOutlet MyWebView *webView;
@end
@implementation WebViewController
- (void)viewDidLoad {
[super viewDidLoad];
UIBarButtonItem *button = [[UIBarButtonItem alloc]initWithImage:[UIImage imageNamed:@"返回"] 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調(diào)用OC:設(shè)置addScriptMessageHandler與name,并且設(shè)置<WKScriptMessageHandler>協(xié)議與協(xié)議方法
[self.webView.configuration.userContentController addScriptMessageHandler:self name:@"callNativeKaihu"];//開戶
}
- (void)viewWillDisappear:(BOOL)animated{
[super viewWillDisappear:animated];
// 移除handlers铛纬,防止內(nèi)存泄露
[self.webView.configuration.userContentController removeScriptMessageHandlerForName:@"callNativeKaihu"];
}
- (void)goBack{
if ([self.webView canGoBack]) {
[self.webView goBack];
}else{
[self.navigationController popViewControllerAnimated:YES];
}
}
#pragma mark - WKScriptMessageHandler
//OC在JS調(diào)用方法做的處理
- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message
{
// 打印所傳過來的參數(shù)模她,只支持NSNumber, NSString, NSDate, NSArray, NSDictionary, NSNull類型
NSLog(@"JS調(diào)用了 %@ 方法,返回參數(shù) %@",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];
}
}
WKWebView默認(rèn)禁止了一些跳轉(zhuǎn)
- UIWebView
打開www.apple.com/itunes/跳轉(zhuǎn)到appStore, 撥打電話, 喚起郵箱等一系列操作UIWebView默認(rèn)支持的。 - WKWebView
默認(rèn)禁止了以上行為,除此之外痛垛,js端通過alert()蹂析,彈窗的動作也被禁掉了俺祠。
如何支持呢?
首先要設(shè)置WKWebView的WKUIDelegate肺然,并實現(xiàn)以下方法
#pragma mark - WKUIDelegate
- (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(void))completionHandler {
// js 里面的alert實現(xiàn)唇撬,如果不實現(xiàn),網(wǎng)頁的alert函數(shù)無效
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:message message:nil preferredStyle:UIAlertControllerStyleAlert];
[alertController addAction:[UIAlertAction actionWithTitle:@"確定" 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 {
// js 里面的alert實現(xiàn),如果不實現(xiàn)晚唇,網(wǎng)頁的alert函數(shù)無效
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:message message:nil preferredStyle:UIAlertControllerStyleAlert];
[alertController addAction:[UIAlertAction actionWithTitle:@"確定" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
completionHandler(YES);
}]];
[alertController addAction:[UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:^(UIAlertAction *action){
completionHandler(NO);
}]];
[self presentViewController:alertController animated:YES completion:^{}];
}
- (void)dealloc{
NSLog(@"觀測web視圖釋放");
}