一个KVO 实现WKWebView加载进度条的例子 (注意最后移除观察者)
Posted liuw_flexi
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了一个KVO 实现WKWebView加载进度条的例子 (注意最后移除观察者)相关的知识,希望对你有一定的参考价值。
// // OpenWebViewController.m // Treasure // // Created by 蓝蓝色信子 on 16/7/29. // Copyright ? 2016年 GY. All rights reserved. // #import "ZTOpenWebViewController.h" #import <WebKit/WebKit.h> @interface ZTOpenWebViewController ()<WKNavigationDelegate> //{ // //网页视图 // UIWebView * _webView; //} @property (strong, nonatomic) WKWebView *webView; @property (strong, nonatomic) UIProgressView *progressView; @end @implementation ZTOpenWebViewController - (void)viewDidLoad { [super viewDidLoad]; // //取消导航栏的影响 self.automaticallyAdjustsScrollViewInsets = NO; self.view.backgroundColor = [UIColor whiteColor]; //[SVProgressHUD show]; //实例化 [self createWebView]; [self creatCustomProgressView]; } -(void)creatCustomProgressView{ //增加加载进度条 // KVO,监听webView属性值得变化(estimatedProgress,title为特定的key) [_webView addObserver:self forKeyPath:@"estimatedProgress" options:NSKeyValueObservingOptionNew context:nil]; [_webView addObserver:self forKeyPath:@"title" options:NSKeyValueObservingOptionNew context:nil]; // UIProgressView初始化 self.progressView = [[UIProgressView alloc] initWithProgressViewStyle:UIProgressViewStyleDefault]; self.progressView.frame = CGRectMake(0, 0, _webView.frame.size.width, 5); self.progressView.trackTintColor = [UIColor clearColor]; // 设置进度条的色彩 self.progressView.progressTintColor = [UIColor magentaColor]; // 设置初始的进度,防止用户进来就懵逼了(微信大概也是一开始设置的10%的默认值) [self.progressView setProgress:0.1 animated:YES]; [_webView addSubview:self.progressView]; } - (void)viewWillAppear:(BOOL)animated { [self.navigationController setNavigationBarHidden:NO animated:NO]; [super viewWillAppear:YES]; } - (void)viewWillDisappear:(BOOL)animated { [SVProgressHUD dismiss]; [super viewWillDisappear:animated]; } - (void)createWebView { _webView = [[WKWebView alloc]initWithFrame:self.view.bounds]; [self.view addSubview:_webView]; //调整适应比例 //_webView.scalesPageToFit = YES; //设置代理 _webView.navigationDelegate = self; [[NSURLCache sharedURLCache] removeAllCachedResponses]; [_webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:self.urlStr] cachePolicy:NSURLRequestReloadIgnoringLocalAndRemoteCacheData timeoutInterval:10.0]]; } #pragma mark - WKWebView NavigationDelegate //WKNavigationDelegate - (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler { //NSLog(@"是否允许这个导航"); decisionHandler(WKNavigationActionPolicyAllow); } - (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler { // Decides whether to allow or cancel a navigation after its response is known. //NSLog(@"知道返回内容之后,是否允许加载,允许加载"); decisionHandler(WKNavigationResponsePolicyAllow); } - (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(null_unspecified WKNavigation *)navigation { //NSLog(@"开始加载"); //self.progress.alpha = 1; //[SVProgressHUD show]; [UIApplication sharedApplication].networkActivityIndicatorVisible = YES; } - (void)webView:(WKWebView *)webView didReceiveServerRedirectForProvisionalNavigation:(null_unspecified WKNavigation *)navigation { //NSLog(@"跳转到其他的服务器"); } - (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(null_unspecified WKNavigation *)navigation withError:(NSError *)error { //NSLog(@"网页由于某些原因加载失败"); //[SVProgressHUD dismiss]; //self.progress.alpha = 0; [UIApplication sharedApplication].networkActivityIndicatorVisible = NO; } - (void)webView:(WKWebView *)webView didCommitNavigation:(null_unspecified WKNavigation *)navigation { //NSLog(@"网页开始接收网页内容"); } - (void)webView:(WKWebView *)webView didFinishNavigation:(null_unspecified WKNavigation *)navigation { //NSLog(@"网页导航加载完毕"); //[SVProgressHUD dismiss]; [UIApplication sharedApplication].networkActivityIndicatorVisible = NO; self.title = webView.title; [webView evaluatejavascript:@"document.title" completionHandler:^(id _Nullable ss, NSError * _Nullable error) { //NSLog(@"----document.title:%@---webView title:%@",ss,webView.title); }]; //self.progress.alpha = 0; } - (void)webView:(WKWebView *)webView didFailNavigation:(null_unspecified WKNavigation *)navigation withError:(NSError *)error { //NSLog(@"加载失败,失败原因:%@",[error description]); //self.progress.alpha = 0; } - (void)webViewWebContentProcessDidTerminate:(WKWebView *)webView { //NSLog(@"网页加载内容进程终止"); } #pragma mark - KVO监听 // 第三部:完成监听方法 - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { if ([object isEqual:_webView] && [keyPath isEqualToString:@"estimatedProgress"]) { // 进度条 CGFloat newprogress = [[change objectForKey:NSKeyValueChangeNewKey] doubleValue]; //NSLog(@"打印测试进度值:%f", newprogress); if (newprogress == 1) { // 加载完成 // 首先加载到头 [self.progressView setProgress:newprogress animated:YES]; // 之后0.3秒延迟隐藏 __weak typeof(self) weakSelf = self; dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0.3 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{ weakSelf.progressView.hidden = YES; [weakSelf.progressView setProgress:0 animated:NO]; }); } else { // 加载中 self.progressView.hidden = NO; [self.progressView setProgress:newprogress animated:YES]; } } else if ([object isEqual:_webView] && [keyPath isEqualToString:@"title"]) { // 标题 //self.title = _webView.title; } else { // 其他 [super observeValueForKeyPath:keyPath ofObject:object change:change context:context]; } } -(void)dealloc{ NSLog(@"webVC dealloc = %@",self); [_webView removeObserver:self forKeyPath:@"estimatedProgress"]; [_webView removeObserver:self forKeyPath:@"title"]; } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } /* #pragma mark - Navigation // In a storyboard-based application, you will often want to do a little preparation before navigation - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { // Get the new view controller using [segue destinationViewController]. // Pass the selected object to the new view controller. } */ @end
以上是关于一个KVO 实现WKWebView加载进度条的例子 (注意最后移除观察者)的主要内容,如果未能解决你的问题,请参考以下文章