WKWebView的使用

来源:互联网 发布:知乎 上知网 编辑:程序博客网 时间:2024/06/05 00:41

iOS8 以前我们是通过UIWebView加载网页的,但是通过UIWebView网页加载一直存在不少问题:加载速度慢,占用内存多,优化困难等;iOS8以后,苹果推出了WebKit新框架,可以通过新的UI组件WKWebView来替代原来的UIWebView,新推出的WKWebView速度更快了,占用内存少了,妈妈再也不用担心我们家在网页了!


WKWebView 有两个代理:一个WKNavigationDelegate、WKUIDelegate,先来看看WKNavigationDelegate的代理方法.

以下是用来处理跳转的代理方法:

// 发送request后,收到响应后调用- (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler;// 发送request请求网页之前调用- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler;// 接收到服务器跳转请求之后调用- (void)webView:(WKWebView *)webView didReceiveServerRedirectForProvisionalNavigation:(WKNavigation *)navigation;


注意:在苹果开发中,一般遇到block的名称是以xxxHandler结尾的,都是需要去实现的.


以下是用来处理加载状态的代理方法:

- (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(WKNavigation *)navigation{        NSLog(@"网页开始加载时调用:%s",__func__);}- (void)webView:(WKWebView *)webView didCommitNavigation:(WKNavigation *)navigation{        NSLog(@"加载到内容开始返回时调用:%s",__func__);}- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation{    NSLog(@"网页加载完成之后调用:%s",__func__);}- (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(WKNavigation *)navigation{     NSLog(@"网页加载失败时调用:%s",__func__);    }

接下来看看WKUIDelegate代理方法:

WKUIDelegate主要用于处理web界面的三种提示框(警告框alert、确认框confirm、输入框prompt),JS调用alert、confirm、prompt时,不采用JS原生的提示,而是使用iOS原生来实现。
// 警告框alert- (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(void))completionHandler;//确认框confirm- (void)webView:(WKWebView *)webView runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(BOOL result))completionHandler;//输入框prompt- (void)webView:(WKWebView *)webView runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(nullable NSString *)defaultText initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(NSString * __nullable result))completionHandler;

接下来再看WKWebView与JS交互的问题:该方法主要处理JS交互
- (void)evaluateJavaScript:(NSString *)javaScriptString completionHandler:(void (^ __nullable)(__nullable id, NSError * __nullable error))completionHandler;

废话不多说,直接上源代码了:
#import "ViewController.h"@import WebKit;@interface ViewController ()<WKNavigationDelegate,WKUIDelegate,UIGestureRecognizerDelegate>@property (nonatomic, strong) WKWebView *webView;@end@implementation ViewController- (WKWebView *)webView{    if (_webView == nil) {        _webView = [[WKWebView alloc]initWithFrame:self.view.bounds];        _webView.navigationDelegate = self;        _webView.UIDelegate = self;                UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(tapWebView:)];        tap.delegate = self;        [_webView addGestureRecognizer:tap];    }    return _webView;}- (void)tapWebView:(UITapGestureRecognizer *)gesture{        CGPoint point = [gesture locationInView:self.webView];    NSString *js = [NSString stringWithFormat:@"imageSourceFromPoint(%g,%g)",point.x,point.y];        [self.webView evaluateJavaScript:js completionHandler:^(id _Nullable result, NSError * _Nullable error) {        NSLog(@"====>%@",result);    }];    }#pragma mark -- UIGestureRecognizerDelegate//允许多个手势- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer{    return YES;}- (void)viewDidLoad {    [super viewDidLoad];    // Do any additional setup after loading the view, typically from a nib.    NSString *urlStr = @"http://www.jianshu.com/p/25d06cb451bf";    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:urlStr]];    [self.webView loadRequest:request];    [self.view addSubview:self.webView];    }#pragma mark - WKUIDelegate// JS调用alert、confirm、prompt时,不采用JS原生提示,而是使用iOS原生来实现- (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(void))completionHandler{        UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"提示" message:message preferredStyle:UIAlertControllerStyleAlert];    [alert addAction:[UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {        completionHandler();    }]];        [self presentViewController:alert animated:YES completion:NULL];}#pragma mark - WKNavigationDelegate- (void)webView:(WKWebView *)webView didReceiveServerRedirectForProvisionalNavigation:(WKNavigation *)navigation{    NSLog(@"接收到服务器跳转请求之后调用:%s",__func__);}- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler{        NSLog(@"发送request请求网页之前调用:%s",__func__);    //必须处理,决定是否进行跳转    //decisionHandler(WKNavigationActionPolicyCancel);不允许跳转    decisionHandler(WKNavigationActionPolicyAllow);//允许跳转}- (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler{    NSLog(@"发送request后,收到响应后调用:%s",__func__);    // NSLog(@"%@",navigationResponse.response);    decisionHandler(WKNavigationResponsePolicyAllow);}- (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(WKNavigation *)navigation{        NSLog(@"网页开始加载时调用:%s",__func__);}- (void)webView:(WKWebView *)webView didCommitNavigation:(WKNavigation *)navigation{        NSLog(@"加载到内容开始返回时调用:%s",__func__);}- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation{    NSLog(@"网页加载完成之后调用:%s",__func__);        [self.webView evaluateJavaScript:[self loadJSFile] completionHandler:nil];}- (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(WKNavigation *)navigation{     NSLog(@"网页加载失败时调用:%s",__func__);    }// 加载js文件- (NSString *)loadJSFile{    NSURL *url = [[NSBundle mainBundle]URLForResource:@"images.js" withExtension:nil];    return [NSString stringWithContentsOfURL:url encoding:NSUTF8StringEncoding error:NULL];}@end

javascript文件的源代码:
function imageSourceFromPoint(x,y){var element = document.elementFromPoint(x,y);if (element.tagName == 'IMG' && element.src) {var rect = element.getBoundingClientRect();alert(rect.top + '|' + rect.left + '|' + rect.bottom + '|' + rect.right);return element.src;};return null;}








0 0
原创粉丝点击