1. 程式人生 > >一個KVO 實現WKWebView加載進度條的例子 (註意最後移除觀察者)

一個KVO 實現WKWebView加載進度條的例子 (註意最後移除觀察者)

svi anim red all ini 一個 lap eat its

//
//  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加載進度條的例子 (註意最後移除觀察者)