WKWebView的学习
重新整理前面的学习笔记
WKWebView 原文网址 :http://www.jianshu.com/p/7bb5f15f1daa
@interface ViewController ()<WKScriptMessageHandler,WKNavigationDelegate,WKUIDelegate>
//webView
@property(nonatomic,strong)WKWebView *webView;
//进度条
@property(nonatomic,strong)UIProgressView *progressView;
@end
@implementation ViewController
-(void)viewWillDisappear:(BOOL)animated{
[super viewWillDisappear:animated];
//移除监听
[self.webView removeObserver:self forKeyPath:@"loading"];
[self.webView removeObserver:self forKeyPath:@"title"];
[self.webView removeObserver:self forKeyPath:@"estimatedProgress"];
}
- (void)dealloc {
[self.webview removeObserver:self forKeyPath:@"loading"];
[self.webview removeObserver:self forKeyPath:@"estimatedProgress”];
}
- (void)viewDidLoad {
[super viewDidLoad];
[self creatWebView];
[self creatProgressView];
//添加KVO监听
[self.webView addObserver:self
forKeyPath:@"loading"
options:NSKeyValueObservingOptionNew
context:nil];
[self.webView addObserver:self
forKeyPath:@"title"
options:NSKeyValueObservingOptionNew
context:nil];
[self.webView addObserver:self
forKeyPath:@"estimatedProgress"
options:NSKeyValueObservingOptionNew
context:nil];
self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"后退" style:UIBarButtonItemStyleDone target:self action:@selector(goback)];
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"前进" style:UIBarButtonItemStyleDone target:self action:@selector(gofarward)];
}
-(void)goback{
if ([self.webView canGoBack]) {
[self.webView goBack];
NSLog(@"back");
}
}
-(void)gofarward{
if ([self.webView canGoForward]) {
[self.webView goForward];
}
}
-(void)creatProgressView{
self.progressView = [[UIProgressView alloc]initWithFrame:self.view.bounds];
self.progressView.backgroundColor = [UIColor redColor];
[self.view addSubview:self.progressView];
}
//创建webView
-(void)creatWebView{
WKWebViewConfiguration *config = [WKWebViewConfiguration new];
//初始化偏好设置属性:preferences
config.preferences = [WKPreferences new];
//The minimum font size in points default is 0;
config.preferences.minimumFontSize = 10;
//是否支持JavaScript
config.preferences.javaScriptEnabled = YES;
//不通过用户交互,是否可以打开窗口
config.preferences.javaScriptCanOpenWindowsAutomatically = NO;
//通过JS与webView内容交互
config.userContentController = [WKUserContentController new];
// 注入JS对象名称senderModel,当JS通过senderModel来调用时,我们可以在WKScriptMessageHandler代理中接收到
[config.userContentController addScriptMessageHandler:self name:@"senderModel"];
self.webView = [[WKWebView alloc]initWithFrame:self.view.bounds configuration:config];
//1.加载网页
NSURL *url = [NSURL URLWithString:@" http://www.baidu.com"];
NSURLRequest *request = [[NSURLRequest alloc]initWithURL:url];
[webView loadRequest:request];
//2.或者加载本地的测试网页
NSURL *path = [[NSBundle mainBundle]URLForResource:@"WKWebViewText" withExtension:@"html"];
NSURLRequest *request = [NSURLRequest requestWithURL:path];
[webView loadRequest:request];
self.webView.navigationDelegate = self;
self.webView.UIDelegate = self;
}
#pragma mark - KVO监听函数
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context{
if ([keyPath isEqualToString:@"title"]) {
self.title = self.webView.title;
}else if([keyPath isEqualToString:@"loading"]){
NSLog(@"loading");
}
else if ([keyPath isEqualToString:@"estimatedProgress"]){
//estimatedProgress取值范围是0-1;
self.progressView.progress = self.webView.estimatedProgress;
}
if (!self.webView.loading) {
[UIView animateWithDuration:0.5 animations:^{
self.progressView.alpha = 0;
}];
}
}
#pragma mark - WKScriptMessageHandler
-(void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message{
//这里可以通过name处理多组交互,JS调用OC
if ([message.name isEqualToString:@"senderModel"]) {
//body只支持NSNumber, NSString, NSDate, NSArray,NSDictionary 和 NSNull类型
NSLog(@"%@",message.body);
}
}
#pragma mark = WKNavigationDelegate
//在发送请求之前,决定是否跳转 也可用于是否拦截请求
-(void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler{
NSString *hostname = navigationAction.request.URL.host.lowercaseString;
NSLog(@"%@",hostname);
if (navigationAction.navigationType == WKNavigationTypeLinkActivated
&& ![hostname containsString:@".baidu.com"]) {
// 对于跨域,需要手动跳转
[[UIApplication sharedApplication] openURL:navigationAction.request.URL];
// 不允许web内跳转
decisionHandler(WKNavigationActionPolicyCancel);
} else {
self.progressView.alpha = 1.0;
decisionHandler(WKNavigationActionPolicyAllow);
}
}
//在响应完成时,调用的方法。如果设置为不允许响应,web内容就不会传过来
-(void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler{
decisionHandler(WKNavigationResponsePolicyAllow);
}
//接收到服务器跳转请求之后调用
-(void)webView:(WKWebView *)webView didReceiveServerRedirectForProvisionalNavigation:(WKNavigation *)navigation{
}
//开始加载时调用
-(void)webView:(WKWebView *)webView didStartProvisionalNavigation:(WKNavigation *)navigation{
}
//当内容开始返回时调用
-(void)webView:(WKWebView *)webView didCommitNavigation:(WKNavigation *)navigation{
}
//页面加载完成之后调用
-(void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation{
NSLog(@"title:%@",webView.title);
}
// 页面加载失败时调用
- (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(WKNavigation *)navigation
{
}
#pragma mark WKUIDelegate
//alert 警告框
-(void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(void))completionHandler{
UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"警告" message:@"调用alert提示框" preferredStyle:UIAlertControllerStyleAlert];
[alert addAction:[UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
completionHandler();
}]];
[self presentViewController:alert animated:YES completion:nil];
NSLog(@"alert message:%@",message);
}
//confirm 确认框
-(void)webView:(WKWebView *)webView runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(BOOL))completionHandler{
UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"确认框" message:@"调用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(@"confirm message:%@", message);
}
- (void)webView:(WKWebView *)webView runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(nullable NSString *)defaultText initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(NSString * __nullable result))completionHandler {
UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"输入框" message:@"调用输入框" preferredStyle:UIAlertControllerStyleAlert];
[alert addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) {
textField.textColor = [UIColor blackColor];
}];
[alert addAction:[UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
completionHandler([[alert.textFields lastObject] text]);
}]];
[self presentViewController:alert animated:YES completion:NULL];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end
`
"WKWebViewText.html" JavaScript部分的代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>iOS与H5交互练习</title>
<style type="text/css">
*{
font-size: 50px;
}
</style>
</head>
<body>
<h1>一起来学习吧!</h1>
<div><input type="button" value="Alert 提示框" onclick="callJsAlert()"></div>
<br/>
<div><input type="button" value="Confirm 提示框" onclick="callJsConfirm()"></div><br/>
<div>
<div><input type="button" value="Prompt 提示框" onclick="callJsInput()"></div><br/>
<div>Click me here: <a href="http://www.baidu.com">百度</a></div>
</div>
<br/>
<div id="SwiftDiv">
<span id="jsParamFuncSpan" style="color: orange; font-size: 50px;"></span>
</div>
<script type="text/javascript">
function callJsAlert() {
alert('Please show alert');
window.webkit.messageHandlers.senderModel.postMessage({body: 'Alert'});
}
function callJsConfirm() {
if (confirm('Confirm', 'Please show confirm')) {
document.getElementById('jsParamFuncSpan').innerHTML
= 'true';
} else {
document.getElementById('jsParamFuncSpan').innerHTML
= 'false';
}
window.webkit.messageHandlers.senderModel.postMessage({body: 'Confirm'});
}
function callJsInput() {
var response = prompt('Hello', 'Please input a Text:');
document.getElementById('jsParamFuncSpan').innerHTML = response;
window.webkit.messageHandlers.senderModel.postMessage({body: response});
}
</script>
</body>
</html>
`