• WKWebView的使用


    本篇文章的例子是我的一个Demo,我直接复制的.m文件,没有分开写,可能你只是部分需要,需要自己手动去摘取,不全面,以后我会追加的

    #import "ViewController.h"
    #import <Masonry.h>
    #import <WebKit/WebKit.h>
    
    @interface ViewController ()<WKNavigationDelegate,WKUIDelegate,WKScriptMessageHandler>
    @property(nonatomic,strong)WKWebView *webView;
    //设置加载进度条
    @property (nonatomic,strong) UIProgressView *progressView;
    @end
    @implementation ViewController
    - (UIProgressView *)progressView{
        if (!_progressView) {
            _progressView = [[UIProgressView alloc]initWithProgressViewStyle:UIProgressViewStyleDefault];
            // 设置进度条的色彩
            [_progressView setTrackTintColor:[UIColor colorWithRed:240.0/255 green:240.0/255 blue:240.0/255 alpha:1.0]];
            _progressView.progressTintColor = [UIColor orangeColor];
        }
        return _progressView;
    }
    -(WKWebView *)webView{
        if(!_webView){
            //WKWebViewConfiguration配置文件
            WKWebViewConfiguration *config = [[WKWebViewConfiguration alloc] init];
            //允许视频播放
            config.allowsAirPlayForMediaPlayback = YES;
            // 允许在线播放
            config.allowsInlineMediaPlayback = YES;
            // 允许可以与网页交互,选择视图
            config.selectionGranularity = YES;
            // web内容处理池
            config.processPool = [[WKProcessPool alloc] init];
            // 是否支持记忆读取
            config.suppressesIncrementalRendering = YES;
            //自定义配置,一般用于 js调用oc方法(OC拦截URL中的数据做自定义操作)
            WKUserContentController * userContentController = [[WKUserContentController alloc]init];
            // 添加消息处理,注意:self指代的对象需要遵守WKScriptMessageHandler协议,结束时需要移除 这里是监听的时间方法,成功了之后执行WKScriptMessageHandler协议方法
            [userContentController addScriptMessageHandler:self name:@"shareIOS"];
            [userContentController addScriptMessageHandler:self name:@"closeWebViewIOS"];
            
            config.userContentController = userContentController;
            
            _webView = [[WKWebView alloc]initWithFrame:CGRectZero configuration:config];
            [_webView sizeToFit];//适应你设定的尺寸
    //        _webView.allowsBackForwardNavigationGestures = YES;//开启手势触摸
            
            // 设置代理
            _webView.navigationDelegate = self;
            _webView.UIDelegate = self;
        }
        return _webView;
    }
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        self.navigationController.navigationBarHidden = YES;
        
    
        [self.webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"https://www.xxxxx.com?a=b"]]];
        [self.view addSubview:self.webView];
        [self.webView mas_makeConstraints:^(MASConstraintMaker *make) {
            make.left.offset(0);
            make.size.equalTo(self.view);
            make.top.offset(-20);
        }];
        [self.webView addSubview:self.progressView];
        [self.progressView mas_makeConstraints:^(MASConstraintMaker *make) {
            make.top.left.right.offset(0);
            make.height.offset(2);
        }];
        
        // 给webview添加监听
        [self.webView addObserver:self forKeyPath:@"estimatedProgress" options:NSKeyValueObservingOptionOld | NSKeyValueObservingOptionNew context:nil];
    }
    - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context{
        if ([keyPath isEqual:@"estimatedProgress"] && object == self.webView) {
            [self.progressView setAlpha:1.0f];
            [self.progressView setProgress:self.webView.estimatedProgress animated:YES];
            if (self.webView.estimatedProgress  >= 1.0f) {
                [UIView animateWithDuration:0.3 delay:0.3 options:UIViewAnimationOptionCurveEaseOut animations:^{
                    [self.progressView setAlpha:0.0f];
                } completion:^(BOOL finished) {
                    [self.progressView setProgress:0.0f animated:YES];
                }];
            }
        }else{
            [super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
        }
    }
    
    #pragma mark ================ WKUIDelegate ================
    // 警告框
    -(void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(void))completionHandler{
        NSLog(@"------------------------------------------------------------runJavaScriptAlertPanelWithMessage");
        UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"提示" message:@"警告框" preferredStyle:UIAlertControllerStyleAlert];
        [alert addAction:[UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
            completionHandler();
        }]];
        
        [self presentViewController:alert animated:YES completion:NULL];
    }
    
    // 确认框
    -(void)webView:(WKWebView *)webView runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(BOOL))completionHandler{
        NSLog(@"------------------------------------------------------------runJavaScriptConfirmPanelWithMessage");
        UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"提示" message:@"确认框" 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];
    }
    
    // 输入框
    -(void)webView:(WKWebView *)webView runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(NSString *)defaultText initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(NSString * _Nullable))completionHandler{
        NSLog(@"------------------------------------------------------------runJavaScriptTextInputPanelWithPrompt");
        UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"textinput" message:@"输入框" preferredStyle:UIAlertControllerStyleAlert];
        [alert addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) {
            textField.textColor = [UIColor redColor];
        }];
        [alert addAction:[UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
            completionHandler([[alert.textFields lastObject] text]);
        }]];
        
        [self presentViewController:alert animated:YES completion:NULL];
        
    }
    // webview关闭时回调
    - (void)webViewDidClose:(WKWebView *)webView NS_AVAILABLE(10_11, 9_0){
        
    }
    // 默认预览元素调用
    - (BOOL)webView:(WKWebView *)webView shouldPreviewElement:(WKPreviewElementInfo *)elementInfo {
        
        NSLog(@"-----默认预览元素调用");
        return YES;
    }
    // 返回一个视图控制器将导致视图控制器被显示为一个预览。返回nil将WebKit的默认预览的行为。
    - (nullable UIViewController *)webView:(WKWebView *)webView previewingViewControllerForElement:(WKPreviewElementInfo *)elementInfo defaultActions:(NSArray<id <WKPreviewActionItem>> *)previewActions {
        
        NSLog(@"----返回一个视图控制器将导致视图控制器被显示为一个预览。返回nil将WebKit的默认预览的行为。");
        return self;
    }
    
    // 允许应用程序向它创建的视图控制器弹出
    - (void)webView:(WKWebView *)webView commitPreviewingViewController:(UIViewController *)previewingViewController {
        
        NSLog(@"----允许应用程序向它创建的视图控制器弹出");
        
    }
    
    // 显示一个文件上传面板。completionhandler完成处理程序调用后打开面板已被撤销。通过选择的网址,如果用户选择确定,否则为零。如果不实现此方法,Web视图将表现为如果用户选择了取消按钮。
    - (void)webView:(WKWebView *)webView runOpenPanelWithParameters:(WKOpenPanelParameters *)parameters initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(NSArray<NSURL *> * _Nullable URLs))completionHandler {
        
        NSLog(@"----显示一个文件上传面板");
        
    }
    
    #pragma mark ================ WKScriptMessageHandler ================
    
    //拦截执行网页中的JS方法
    - (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message{
        
        //服务器固定格式写法 window.webkit.messageHandlers.名字.postMessage(内容);
        //客户端写法 message.name isEqualToString:@"名字"]
    //    message.name是方法名字  message.body方法的参数
        NSLog(@"------------------------:%@     %@",message.name,message.body);
        
        if ([message.name isEqualToString:@"shareIOS"]) {
           //这里写事件
        }else if ([message.name isEqualToString:@"closeWebViewIOS"]){
           //这里写事件
        }
    }
    - (void)dealloc{
        [self.webView.configuration.userContentController removeScriptMessageHandlerForName:@"shareIOS"];
        [self.webView.configuration.userContentController removeScriptMessageHandlerForName:@"closeWebViewIOS"];
        
        
        [self.webView removeObserver:self forKeyPath:@"estimatedProgress"];
        [self.webView setNavigationDelegate:nil];
        [self.webView setUIDelegate:nil];
        
        
    }
    #pragma mark ================ WKNavigationDelegate ================
    // 1 在发送请求之前,决定是否跳转
    - (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler {
        NSString *urlStr = navigationAction.request.URL.absoluteString;
        NSLog(@"1-------在发送请求之前,决定是否跳转  -->%@",urlStr);
    //    if([urlStr hasPrefix:@"http:"]){
    //        decisionHandler(WKNavigationActionPolicyAllow);如果跳转使用这个
    //    }else{
    //        decisionHandler(WKNavigationActionPolicyCancel);如果不跳转使用这个
    //    }
        decisionHandler(WKNavigationActionPolicyAllow);
    }
    
    // 2 页面开始加载时调用
    - (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(WKNavigation *)navigation {
        NSLog(@"2-------页面开始加载时调用");
    }
    
    // 3 在收到响应后,决定是否跳转
    - (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler {
        /// 在收到服务器的响应头,根据response相关信息,决定是否跳转。decisionHandler必须调用,来决定是否跳转,参数WKNavigationActionPolicyCancel取消跳转,WKNavigationActionPolicyAllow允许跳转
        
        NSLog(@"3-------在收到响应后,决定是否跳转---:");
        
        decisionHandler(WKNavigationResponsePolicyAllow);
    
    }
    
    // 4 当内容开始返回时调用
    - (void)webView:(WKWebView *)webView didCommitNavigation:(WKNavigation *)navigation {
        NSLog(@"4-------当内容开始返回时调用");
    }
    
    // 5 页面加载完成之后调用
    - (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation {
        NSLog(@"5-------页面加载完成之后调用");
    }
    
    // 6 页面加载失败时调用
    - (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(WKNavigation *)navigation {
        
        NSLog(@"6-------页面加载失败时调用");
    }
    
    // 接收到服务器跳转请求之后调用
    - (void)webView:(WKWebView *)webView didReceiveServerRedirectForProvisionalNavigation:(WKNavigation *)navigation {
        NSLog(@"-------接收到服务器跳转请求之后调用");
    }
    
    // 数据加载发生错误时调用
    - (void)webView:(WKWebView *)webView didFailNavigation:(null_unspecified WKNavigation *)navigation withError:(NSError *)error {
        NSLog(@"----数据加载发生错误时调用");
    }
    
    // 需要响应身份验证时调用 同样在block中需要传入用户身份凭证
    - (void)webView:(WKWebView *)webView didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential * _Nullable credential))completionHandler {
        //用户身份信息
        
        NSLog(@"----需要响应身份验证时调用 同样在block中需要传入用户身份凭证");
        
        NSURLCredential *newCred = [NSURLCredential credentialWithUser:@""
                                                              password:@""
                                                           persistence:NSURLCredentialPersistenceNone];
        // 为 challenge 的发送方提供 credential
        [[challenge sender] useCredential:newCred forAuthenticationChallenge:challenge];
        completionHandler(NSURLSessionAuthChallengeUseCredential,newCred);
    }
    
    // 进程被终止时调用
    - (void)webViewWebContentProcessDidTerminate:(WKWebView *)webView {
        NSLog(@"----------进程被终止时调用");
    }
    
    @end
    

    以上是webview给OC传值,如果OC给webview给传值

    //需要传递的数据
    NSMutableDictionary *dic = [NSMutableDictionary new];
    dic[@"token"] = @"11111";
    
    NSData *data = [NSJSONSerialization dataWithJSONObject:dic options:(NSJSONWritingPrettyPrinted) error:nil];
    
    NSString *jsonStr = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
    NSString *js = [NSString stringWithFormat:@"window.iOSInfo = %@", jsonStr];
    //传输的数据
    WKUserScript *script = [[WKUserScript alloc] initWithSource:js injectionTime:(WKUserScriptInjectionTimeAtDocumentStart) forMainFrameOnly:YES];
    
    [self.configuration.userContentController addUserScript:script];
    

    webview调用js的方法

    NSDictionary *dic = @{ @"username": @"lpp",@"sex": @"女"};
    NSString *source = [NSString stringWithFormat:@"jsMethod.setUserInfo(%@)", [dic toJSONString]];
        [self.webView evaluateJavaScript:source completionHandler:^(id _Nullable callbackData, NSError * _Nullable error) {
            if (error) {
                NSLog(@"evaluate js setUserInfo fucntion error %@", error);
                return;
            }
    }];
    

     

  • 相关阅读:
    第八节 JS运动基础
    第七节 DOM操作应用-高级
    第六节 DOM操作应用
    第五讲 DOM基础
    第二节 数学基础与语言学基础
    第一节 自然语言处理概论
    第0节 课程简述
    第四节 定时器
    基本概念
    常用命令
  • 原文地址:https://www.cnblogs.com/hualuoshuijia/p/11435120.html
Copyright © 2020-2023  润新知