美文网首页
给网页添加加载进度条

给网页添加加载进度条

作者: 我太难了_9527 | 来源:发表于2018-01-22 15:50 被阅读0次
    在我们开发 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

    相关文章

      网友评论

          本文标题:给网页添加加载进度条

          本文链接:https://www.haomeiwen.com/subject/cbglaxtx.html