给网页添加加载进度条

在我们开发 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

你可能感兴趣的:(给网页添加加载进度条)