零基础iOS开发学习日记—控件篇—WKWebView

1,408 阅读3分钟

开头

WKWebView

实际用处

  • 显示网页

基础用法

  • 由于WKWebView与网页有关,所有很多东西都涉及到前端的一些知识,我是有会一点皮毛,所以勉强能看得懂,如果完全没接触过前端,建议掌握基础用法就好,不然看起来蛮头疼
  • 使用WKWebView,需要导入头文件WebKit/WebKit.h
  • 因为要替换本身的view,所以在loadView中创建webView,与loadView相关的整理在modal跳转与视图生命周期
  • 加载网页
- (void)loadView {
    self.webView = [[WKWebView alloc] initWithFrame:[UIScreen mainScreen].bounds];
    self.view = self.webView;
}
- (void)viewDidLoad {
    [super viewDidLoad];
    NSURL *url = [NSURL URLWithString:@"http://www.baidu.com"];
    NSURLRequest *request = [NSURLRequest requestWithURL:url];
    //网页界面相关的代理
    self.webView.UIDelegate = self;
    //生命周期
    self.webView.navigationDelegate = self;
    [self.webView loadRequest:request];
}
  • 加载本地pdf、doc、html等
NSURL *url = [[NSBundle mainBundle] URLForResource:@"史提夫乔布斯传.pdf" withExtension:nil];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
[self.webView loadRequest:request];

WKWebViewConfiguration

  • 用于配置webView,例如缩放,自动检测特殊文本、播放媒体配置等
WKWebViewConfiguration *webViewConfig = [WKWebViewConfiguration new];
 //自动监测邮件地址和网址
webViewConfig.dataDetectorTypes = WKDataDetectorTypeAll;
//视频播放画中画
webViewConfig.allowsPictureInPictureMediaPlayback = YES;
//是否直接在h5内播放
webViewConfig.allowsInlineMediaPlayback = YES;
self.webView = [[WKWebView alloc] initWithFrame:[UIScreen mainScreen].bounds configuration:webViewConfig];
  • 其中dataDetectorTypes,这个属性很奇怪,html中的文本内容放在超链接<a>就没效果

WKWebView调用周期函数

  • 以下是常用的,还有关于权限访问的
  • 正常的调用周期和顺序如下
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler{
    NSLog(@"是否跳转 decidePolicyForNavigationAction");
}
- (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(WKNavigation *)navigation {
    NSLog(@"开始加载 didStartProvisionalNavigation");
}
- (void)webView:(WKWebView *)webView didCommitNavigation:(WKNavigation *)navigation {
    NSLog(@"处理网页内容 didCommitNavigation");
}
- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation{
    NSLog(@"完成了 didFinishNavigation");
}
  • 错误处理
  1. 加载错误,访问错误的网址或者不存在的网址
- (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(WKNavigation *)navigation withError:(NSError *)error {
    NSLog(@"加载失败 didFailProvisionalNavigation");
}
  1. 处理返回内容错误
- (void)webView:(WKWebView *)webView didFailNavigation:(WKNavigation *)navigation withError:(NSError *)error {
    NSLog(@"处理网页返回内容发生失败 didFailNavigation");
}
  1. 访问终止,程序崩溃
- (void)webViewWebContentProcessDidTerminate:(WKWebView *)webView {
    NSLog(@"进程终止 webViewWebContentProcessDidTerminate");
}

网页提示框

  • 主要用处是配合网页的各种框,下面三个函数包含了,三类提示的主要内容,作出相应处理就好
  1. 提示框
- (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(void))completionHandler {
    UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"提示" message:message preferredStyle:UIAlertControllerStyleAlert];
    UIAlertAction *alertAction = [UIAlertAction actionWithTitle:@"确认" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
        completionHandler();
    }];
    [alertController addAction:alertAction];
    [self presentViewController:alertController animated:YES completion:nil];
}
  1. 确认框
- (void)webView:(WKWebView *)webView runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(BOOL))completionHandler {
    NSLog(@"%@", message);
    completionHandler(YES);
}
  1. 输入框
- (void)webView:(WKWebView *)webView runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(NSString *)defaultText initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(NSString * _Nullable))completionHandler {
    
}

OC调用JS

  • OC调用JS,需要把执行的JS代码,作为NSString传入下面这个函数即可
[webView evaluateJavaScript:@"test();" completionHandler:^(id _Nullable data, NSError * _Nullable error) {
        //处理这个函数返回的数据
        NSLog(@"%@", data);
    }];

JS调用OC

  • 主要思路如下
  1. 定义协议,http/https本质上也是一个协议
  2. 处理请求
  • html中的内容<a href = "source:///showMessage:/helloworld">调用oc的方法</a>,第一部分是方法,第二部分是参数
  • 整个过程为,点击超链接文本调用oc的方法->进入下面的函数->判断协议是否为source->调用showMessage:函数,传入helloworld参数
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler{
    NSString *strRequest = [navigationAction.request.URL.absoluteString stringByRemovingPercentEncoding];
    NSURLRequest *myrequest = navigationAction.request;
    //判断协议是否是自定义协议
    if ([myrequest.URL.scheme isEqualToString:@"source"]) {
        //方法名
        NSString *methodName = myrequest.URL.pathComponents[1];
        //参数
        NSString *param = myrequest.URL.pathComponents[2];
        //通过字符串获取方法名
        SEL method = NSSelectorFromString(methodName);
        if([self respondsToSelector:method])
        {
            [self performSelector:method withObject:param];
        }
        
    }
    //处理方式
    decisionHandler(WKNavigationActionPolicyAllow);
}

实现网页点击打电话或者发送邮件

  • html中的内容
<a href = "phone:///makeSms:/10000">10000</a>
  • OC中的内容
  1. 协议判断
if ([myrequest.URL.scheme isEqualToString:@"phone"]) {
    NSLog(@"%@", myrequest.URL.pathComponents);
    //方法名
    NSString *methodName = myrequest.URL.pathComponents[1];
    //参数
    NSString *param = myrequest.URL.pathComponents[2];
    SEL method = NSSelectorFromString(methodName);
    if([self respondsToSelector:method])
    {
        [self performSelector:method withObject:param];
    }
    
}
  1. 发短信
-(void)makeSms:(NSString *)phoneNumber
{
    NSLog(@"发短信");
    UIApplication *app = [UIApplication sharedApplication];
    NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"sms://%@", phoneNumber]];
    [app openURL:url options:@{} completionHandler:nil];
}
  • iOS在调用系统的发短息、打电话和发邮件等功能,都有相关的协议
tel://xxx 打电话
sms://xxx 发短信
mailto://xxx 发邮件
http://xxx 打开网页