一个kvo实现wkwebview加载进度条的例子(注意最后移除观察者)(代码片段)

liuw_flexi liuw_flexi     2022-11-23     331

关键词:

//
//  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

 

前端页面加载进度条的制作

...体验来说体验是很不好的。因此我们可以在页面加载时用一个加载动效来表示,当加载完成的时候,再来显示内容。推荐一个制作进度条的网站icons8.com/preloaders/,制作进入条有以下几种方法。这种方法实现进度条简单粗暴,但... 查看详情

wkwebview获取页面title和加载进度值

排版样式可能不是太好你可以把以下代码全部复制到一个新的UIViewController里面就行实现功能,获取的WebView的标题和进度值//WebCheckViewController.m//FamilySchoolPro////15/11/23由yzq创建。//版权所有©2015年renxiaoxu。版权所有。//#import“We... 查看详情

笔记canvas图片预加载及进度条的实现

/*star*loading模块*实现图片的预加载,并显示进度条*参数:图片数组对象,加载完成的回调函数*/functionloadImages(sources,callback){varloadedImages=0;varnumImages=0;ctx.font=‘14pxbold‘;ctx.lineWidth=5;varclearWidth=canvas.width;varclearHeigh 查看详情

第七章文本进度条的实现(代码片段)

...2、进度条需要能在一行中逐渐变化问题分析:如何获取一个文本进度条的变化时间呢?1、采用sleep()模拟一个持续的进度2、似乎不那么难简单的开始:1#TextProBarV1.py2importtime3scale=104print("------执行开始------")5foriinr 查看详情

带有进度条的按钮 android

...2021-05-2910:54:36【问题描述】:我正在尝试在Android中创建一个带有进度条的自定义按钮。按钮应该有两种状态:正常和正在加载。在正常状态下它应该显示一个文本,而在加载状态下它应该显示一个居中的圆形进度指示器而不是... 查看详情

如何在 SwiftUI 中观察 WKWebView 的加载进度?

】如何在SwiftUI中观察WKWebView的加载进度?【英文标题】:HowtoobserveloadingprogressforWKWebViewinSwiftUI?【发布时间】:2020-09-2104:36:37【问题描述】:我正在使用SwiftUI构建一个Web浏览器,并将视图分为3个部分:SearchView、WebView(UIViewRepresen... 查看详情

使用wkwebview自适应屏幕遇到的问题以及最后解决的方法

...屏幕,有兴趣的话可以自己试一下第二种方法:在初始化WKWebView的时候添加配置可以解决自适应的问题,但是在加载的内容宽度大于高度的时候就有些不准确了,宽度无法自适应屏幕的宽度,最后我也没搞明白是因为什么原因,... 查看详情

libgdx之assetmanager资源管理器及进度条的实现

...我们用到的游戏资源,是直接加载的,由于只是一个demo,资源比较少,因此看不出时间用到的长短。实际上我们在游戏开发过程中用到的图片,声音等资源比较多,这时加载游戏过程中会出现黑屏现象ÿ... 查看详情

使用 Glide 库设置完成图像加载后进度条的可见性

...发布时间】:2014-11-2103:52:30【问题描述】:您好,我想要一个图像进度条,它会在图像加载时显示,但是当图像加载完成时,我想将其设置为消失。早些时候,我为此使用了Picasso库。但我不知道如何将它与Glide库一 查看详情

如何实现带有进度条的启动画面? - 安卓

...发布时间】:2012-06-1722:46:32【问题描述】:我在启动时有一个启动画面。使用以下编码publicclassSplashextendsActivity@OverrideprotectedvoidonCreate(BundlesavedInstanceState)//T 查看详情

u3d异步加载场景以及进度条的显示

1、先建立两个场景 2、把两个场景在在buildsetting中添加两个建好的两个场景3、在第一个场景中建立一个button和slider组件4、代码处理usingUnityEngine;usingSystem.Collections;usingUnityEngine.UI;usingUnityEngine.SceneManagement;publicclassButtonTest:Mo 查看详情

libgdx之assetmanager资源管理器及进度条的实现

...我们用到的游戏资源,是直接加载的,由于只是一个demo,资源比较少,因此看不出时间用到的长短。实际上我们在游戏开发过程中用到的图片,声音等资源比较多,这时加载游戏过程中会出现黑屏现象ÿ... 查看详情

android中webview怎么实现网页加载时显示加载进度?

android中只需要给webView注册一个事件即可实现加载进度。以下是具体实现代码:1.从webView中获取设置 WebSettingssws=webView.getSettings(); sws.setSupportZoom(true); sws.setBuiltInZoomControls(true); webView.setInitialScale(25); webView.getSettings().setUseWideViewP... 查看详情

学习|css3实现进度条加载

...种交互效果,这样做的目的是提高用户体验。进度条的的实现分为3大部分:1、页面布局,2、进度条动效,3、何时进度条增加。文件目录加载文件顺序<linkrel="stylesheet/less"href="./index.less"><scriptsrc="./zepto.min.js"></script>... 查看详情

Adobe Flash Builder:如何制作带有进度条的 SWF 用于加载自身?

...ngitself?【发布时间】:2021-03-0309:38:48【问题描述】:我有一个AS3项目,它的所有资产都使用[Embed]元数据标签嵌入,因为我希望生成的SWF完全独立,以便在Internet上移植。问题:文件大小相当大,我希 查看详情

两个进度条,加上百分比显示(用wpf实现)

...-4054-96af-9c747bf89a6e/ProgressBar.exe以上是微软WPF进度条控件的一个例子,很容易,不是很长,不贴过来了,下载了一看就会,好用加分:) 参考技术BVS里面不是有那个进度条的控件吗!为什么还要用你说的那一个呢!??而且,用里面自带... 查看详情

如何使用 Swing Timer 来延迟进度条的加载

】如何使用SwingTimer来延迟进度条的加载【英文标题】:HowtousetheSwingTimertodelaytheloadingofaprogressbar【发布时间】:2013-03-1802:47:34【问题描述】:我需要找到一种方法来使用带有进度条的摇摆计时器。我尝试使用Thread.sleep(),但是当... 查看详情

ioswkwebview与h5交互,js调oc传值、oc调js传值、进度条加载等(干货满满)

参考技术AWKWebView是苹果在iOS8之后推出的框架,关于它比webview的优势这里就不讲了。主要说一下与JS交互的问题,其实WKWebView已经内置了JS与OC的互调、传值等方法,使用起来也非常方便,下面就来细细的探讨一下以及自己遇到过... 查看详情