给网页添加加载进度条
2018-01-22 本文已影响0人
我太难了_9527
在我们开发 app 的时候往往少不了套网页, 之前我一直用的是 hud 在加载的时候就调用, 结束了就隐藏掉, 那样做用户的体验不怎么好, 于是我就写了 下面这种
QQ20180122-153305-HD.gif
可以增加下用户体验
1 首先需要创建一个 ViewController 需要实现 WKNavigationDelegate,WKUIDelegate 这两个协议
在. h文件里面定义
/**
进度条
*/
@property (nonatomic, strong)YukiWebProgressLayer *webProgressLayer;
/**
webView
*/
@property (nonatomic, strong) WKWebView *webView;
/**
网址链接
*/
@property (nonatomic, copy) NSString *urlString;
/**
进度条颜色
*/
@property (nonatomic, assign) UIColor *progressColor;
.m 中
- (void)viewDidLoad {
[super viewDidLoad];
[self.webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:self.urlString]]];
[self.navigationController.navigationBar.layer addSublayer:self.webProgressLayer];
}
// 页面开始加载时调用
-(void)webView:(WKWebView *)webView didStartProvisionalNavigation:(WKNavigation *)navigation{
[self.webProgressLayer startLoad];
}
// 当内容开始返回时调用
- (void)webView:(WKWebView *)webView didCommitNavigation:(WKNavigation *)navigation
{
}
// 页面加载完成之后调用
-(void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation{
[self.webProgressLayer finishedLoadWithError:nil];
}
// 页面加载失败时调用
-(void)webView:(WKWebView *)webView didFailNavigation:(WKNavigation *)navigation withError:(NSError *)error{
[self.webProgressLayer finishedLoadWithError:error];
}
#pragma mark webView
-(WKWebView *)webView{
if (!_webView) {
_webView = [[WKWebView alloc]initWithFrame:self.view.bounds];
_webView.navigationDelegate = self;
_webView.UIDelegate = self;
_webView.backgroundColor = [UIColor whiteColor];
[self.view addSubview:_webView];
}
return _webView;
}
#pragma mark webProgressLayer
-(YukiWebProgressLayer *)webProgressLayer{
if (!_webProgressLayer) {
_webProgressLayer = [[YukiWebProgressLayer alloc]init];
_webProgressLayer.frame =CGRectMake(0, 42, ScreenWidth, 3);
_webProgressLayer.strokeColor = self.progressColor == nil ? [UIColor blueColor].CGColor : self.progressColor.CGColor;
}
return _webProgressLayer;
}
-(void)backButtonClick:(UIButton *)sender{
[self.webView canGoBack] ? [self.webView goBack] : [self goBack];
}
- (void)dealloc {
[self.webProgressLayer closeTimer];
[_webProgressLayer removeFromSuperlayer];
_webProgressLayer = nil;
}
2 创建YukiWebProgressLayer继承CAShapeLayer
//开始加载
-(void)startLoad;
//加载完成
-(void)finishedLoadWithError:(NSError *)error;
//关闭时间
-(void)closeTimer;
- (void)webViewPathChanged:(CGFloat)estimatedProgress;
static NSTimeInterval const ProgressTimeInterval = 0.03;
@property (nonatomic, strong) CAShapeLayer *layer;
@property (nonatomic, strong) NSTimer *timer;
@property (nonatomic, assign) CGFloat plusWidth;
- (instancetype)init {
self = [super init];
if (self) {
[self initBezierPath];
}
return self;
}
- (void)initBezierPath {
//绘制贝塞尔曲线
UIBezierPath *path = [UIBezierPath bezierPath];
//起点
[path moveToPoint:CGPointMake(0, 3)];
//终点
[path addLineToPoint:CGPointMake(ScreenWidth,3)];
self.path = path.CGPath;
self.strokeEnd = 0;
_plusWidth = 0.005;
self.lineWidth = 2;
self.strokeColor = [UIColor redColor].CGColor;
_timer = [NSTimer scheduledTimerWithTimeInterval:ProgressTimeInterval target:self selector:@selector(pathChanged:) userInfo:nil repeats:YES];
[_timer pauseTime];
}
// 设置进度条增加的进度
- (void)pathChanged:(NSTimer *)timer{
self.strokeEnd += _plusWidth;
if (self.strokeEnd > 0.60) {
_plusWidth = 0.002;
}
if (self.strokeEnd > 0.85) {
_plusWidth = 0.0007;
}
if (self.strokeEnd > 0.93) {
_plusWidth = 0;
}
}
//在KVO 计算 实际的读取进度时,调用改方法
- (void)WebViewPathChanged:(CGFloat)estimatedProgress {
self.strokeEnd = estimatedProgress;
}
//开始加载
-(void)startLoad{
[_timer webPageTimeWithTimeInterval:ProgressTimeInterval];
}
//加载完成
-(void)finishedLoadWithError:(NSError *)error{
CGFloat timer;
if (error == nil) {
[self closeTimer];
timer = 0.5;
self.strokeEnd = 1.0;
}else {
timer = 45.0;
}
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(timer * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
if (timer == 45.0) {
[self closeTimer];
}
self.hidden = YES;
[self removeFromSuperlayer];
});
}
//关闭时间
-(void)closeTimer{
[_timer invalidate];
_timer = nil;
}
- (void)webViewPathChanged:(CGFloat)estimatedProgress{
[self closeTimer];
}
3 写一个 NSTimer 的分类 NSTimer (addition)
/** 暂停时间 */
- (void)pauseTime;
/** 获取内容所在当前时间 */
- (void)webPageTime;
/** 当前时间 time 秒后的时间 */
- (void)webPageTimeWithTimeInterval:(NSTimeInterval)time;
- (void)pauseTime{
//判断定时器是否有效
if (!self.isValid) {
return;
}
//停止计时器
[self setFireDate:[NSDate distantFuture]];
}
- (void)webPageTime{
//判断定时器是否有效
if (!self.isValid) {
return;
}
//返回当期时间
[self setFireDate:[NSDate date]];
}
- (void)webPageTimeWithTimeInterval:(NSTimeInterval)time{
//判断定时器是否有效
if (!self.isValid) {
return;
}
[self setFireDate:[NSDate dateWithTimeIntervalSinceNow:time]];
}
4 使用方法 就如下即可
YukiWebViewController *vc= [YukiWebViewController new];
vc.urlString = @"https://www.baidu.com";//网页 url
vc.progressColor = [UIColor redColor]; //自定义颜色
[self.navigationController pushViewController:vc animated:YES];
当然我这个 webViewController你也可以当成一个父类, 可以创建之类来继承 具体的可以到我的 gitHub 地址 https://github.com/wyxlh/YukiFramework