项目demo链接:https://github.com/MinLee6/WebViewLoadProgress
现在的app常常会嵌入不少的h5页面,这里参照微信显示web页面的方式,做了一个导航栏下的加载进度条.因为项目最低支持iOS7,所以不能使用WKWebView
来加载网页,只能使用 UIWebView
,查看 UIWebView
的API可以发现,并没有代理或是通知告诉我们webView加载了多少,所以这个进度条我决定用虚拟的方式来做,就是假装知道加载了多少.
加载WebView的控制器LMWebController
LMWebController.m
//
// LMWebController.m
// LMWebViewLoadProgress
//
// Created by limin on 17/1/16.
// Copyright © 2017年 君安信(北京)科技有限公司. All rights reserved.
//
#import "LMWebController.h"
#import "LMWebProgressLayer.h"
#import "UIView+Frame.h"
@interface LMWebController ()<UIWebViewDelegate>
@end
@implementation LMWebController
{
UIWebView *_webView;
LMWebProgressLayer *_progressLayer; ///< 网页加载进度条
}
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor whiteColor];
[self setupUI];
}
- (void)setupUI {
_webView = [[UIWebView alloc] initWithFrame:self.view.bounds];
_webView.delegate = self;
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:self.url]];
[_webView loadRequest:request];
_webView.backgroundColor = [UIColor whiteColor];
_progressLayer = [LMWebProgressLayer new];
_progressLayer.frame = CGRectMake(0, 42, SCREEN_WIDTH, 2);
[self.navigationController.navigationBar.layer addSublayer:_progressLayer];
[self.view addSubview:_webView];
}
#pragma mark - UIWebViewDelegate
- (void)webViewDidStartLoad:(UIWebView *)webView {
[_progressLayer startLoad];
}
- (void)webViewDidFinishLoad:(UIWebView *)webView {
[_progressLayer finishedLoad];
self.title = [webView stringByEvaluatingJavaScriptFromString:@"document.title"];
}
- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error {
[_progressLayer finishedLoad];
}
- (void)dealloc {
[_progressLayer closeTimer];
[_progressLayer removeFromSuperlayer];
_progressLayer = nil;
NSLog(@"i am dealloc");
}
@end
进度条:LMWebProgressLayer.h
//
// LMWebProgressLayer.h
// LMWebViewLoadProgress
//
// Created by limin on 17/1/16.
// Copyright © 2017年 君安信(北京)科技有限公司. All rights reserved.
//
#import <QuartzCore/QuartzCore.h>
#import <UIKit/UIKit.h>
#define SCREEN_WIDTH [UIScreen mainScreen].bounds.size.width
@interface LMWebProgressLayer : CAShapeLayer
- (void)finishedLoad;
- (void)startLoad;
- (void)closeTimer;
@end
进度条:LMWebProgressLayer.m
//
// LMWebProgressLayer.m
// LMWebViewLoadProgress
//
// Created by limin on 17/1/16.
// Copyright © 2017年 君安信(北京)科技有限公司. All rights reserved.
//
#import "LMWebProgressLayer.h"
#import "NSTimer+Addition.h"
static NSTimeInterval const kFastTimeInterval = 0.003;
@implementation LMWebProgressLayer
{
CAShapeLayer *_layer;
NSTimer *_timer;
CGFloat _plusWidth; ///< 增加点
}
- (instancetype)init {
if (self = [super init]) {
[self initialize];
}
return self;
}
- (void)initialize {
self.lineWidth = 2;
self.strokeColor = [UIColor greenColor].CGColor;
_timer = [NSTimer scheduledTimerWithTimeInterval:kFastTimeInterval target:self selector:@selector(pathChanged:) userInfo:nil repeats:YES];
[_timer pause];
UIBezierPath *path = [UIBezierPath bezierPath];
[path moveToPoint:CGPointMake(0, 2)];
[path addLineToPoint:CGPointMake(SCREEN_WIDTH, 2)];
self.path = path.CGPath;
self.strokeEnd = 0;
_plusWidth = 0.01;
}
- (void)pathChanged:(NSTimer *)timer {
self.strokeEnd += _plusWidth;
if (self.strokeEnd > 0.8) {
_plusWidth = 0.002;
}
}
- (void)startLoad {
[_timer resumeWithTimeInterval:kFastTimeInterval];
}
- (void)finishedLoad {
[self closeTimer];
self.strokeEnd = 1.0;
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.25 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
self.hidden = YES;
[self removeFromSuperlayer];
});
}
- (void)dealloc {
// NSLog(@"progressView dealloc");
[self closeTimer];
}
#pragma mark - private
- (void)closeTimer {
[_timer invalidate];
_timer = nil;
}
@end
定时器:NSTimer+Addition.h
//
// NSTimer+Addition.h
// LMWebViewLoadProgress
//
// Created by limin on 17/1/16.
// Copyright © 2017年 君安信(北京)科技有限公司. All rights reserved.
//
#import <Foundation/Foundation.h>
@interface NSTimer (Addition)
- (void)pause;
- (void)resume;
- (void)resumeWithTimeInterval:(NSTimeInterval)time;
@end
定时器: NSTimer+Addition.m
//
// NSTimer+Addition.m
// LMWebViewLoadProgress
//
// Created by limin on 17/1/16.
// Copyright © 2017年 君安信(北京)科技有限公司. All rights reserved.
//
#import "NSTimer+Addition.h"
@implementation NSTimer (Addition)
- (void)pause {
if (!self.isValid) return;
[self setFireDate:[NSDate distantFuture]];
}
- (void)resume {
if (!self.isValid) return;
[self setFireDate:[NSDate date]];
}
- (void)resumeWithTimeInterval:(NSTimeInterval)time {
if (!self.isValid) return;
[self setFireDate:[NSDate dateWithTimeIntervalSinceNow:time]];
}
@end