仿UC浏览器图片加载进度条
前几天用UC浏览器看新闻(无意中给UC打了广告),看到它的图片加载进度条,正好最近有时间,所以就自己写了一个。
效果图如下
进度条的底色和填充颜色都可以调整。
首先中间的笑脸作为一个整体,其实现代码如下:
#import "FaceView.h" @implementation FaceView - (instancetype)initWithFrame:(CGRect)frame{ self = [super initWithFrame:frame]; if (self) { self.backgroundColor = [UIColor clearColor]; } return self; } - (void)drawRect:(CGRect)rect{ CGFloat width = rect.size.width; CGFloat height = rect.size.height; CGContextRef context=UIGraphicsGetCurrentContext(); //眼睛 CGFloat eyeRadius = width * 0.1; CGFloat factor_eyeX = 0.3; CGFloat factor_eyeY = 0.2; CGPoint leftEyeCenter = CGPointMake(width * factor_eyeX, height * factor_eyeY); CGPoint RightEyeCenter = CGPointMake(width - width * factor_eyeX, height * factor_eyeY); CGContextAddArc(context, leftEyeCenter.x, leftEyeCenter.y, eyeRadius, 0, M_PI * 2, 0); CGContextAddArc(context, RightEyeCenter.x, RightEyeCenter.y, eyeRadius, 0, M_PI * 2, 0); if (_faceColor) { [_faceColor set]; } CGContextDrawPath(context, kCGPathFill); //嘴 CGFloat factor_pX = 0.15; CGFloat factor_pY = 0.6; CGFloat factor_cX = 0.5; CGFloat factor_cY = 0.8; CGPoint startPoint = CGPointMake(width * factor_pX, height * factor_pY); CGPoint endPoint = CGPointMake(width - width * factor_pX, height * factor_pY); CGPoint controlPoint = CGPointMake(width * factor_cX, height * factor_cY); //贝塞尔曲线 CGContextMoveToPoint(context, startPoint.x, startPoint.y); CGContextAddQuadCurveToPoint(context, controlPoint.x, controlPoint.y, endPoint.x, endPoint.y); CGContextSetLineWidth(context, 2.0); CGContextDrawPath(context, kCGPathStroke); } - (void)setFaceColor:(UIColor *)faceColor{ _faceColor = faceColor; [self setNeedsDisplay]; } - (void)dealloc{ LogFunc;; }
接下来就是路径的绘制代码如下:
#define RGBColor(r, g, b) [UIColor colorWithRed:(r)/255.0 green:(g)/255.0 blue:(b)/255.0 alpha:1.0] #define grayColor RGBColor(138, 138, 138) #import "YXProgressView.h" #import "FaceView.h" @interface YXProgressView () @property (nonatomic,assign) CGFloat rectRadius; @property (nonatomic,assign) CGFloat lineWidth; @property (nonatomic,assign) CGFloat myFaceViewInset; @property (nonatomic,strong) CAShapeLayer *progressLayer; @property (nonatomic,strong) CAShapeLayer *outLayer; @property (nonatomic,strong) FaceView *myFaceView; @property (nonatomic,strong) NSTimer *animatedTimer; @property (nonatomic,assign) NSTimeInterval timeInterval; @end @implementation YXProgressView - (instancetype)initWithFrame:(CGRect)frame{ self = [super initWithFrame:frame]; if (self) { self.backgroundColor = [UIColor clearColor]; self.isAnimated = YES; self.actionLineColor = [UIColor whiteColor]; self.fixedLineColor = grayColor; CGFloat width = frame.size.width; self.myFaceViewInset = width * 0.15; self.rectRadius = width * 0.2; self.lineWidth = 3.0; self.timeInterval = 2.0; self.myFaceView = [FaceView new]; self.myFaceView.faceColor = self.fixedLineColor; [self addSubview:self.myFaceView]; self.outLayer = [CAShapeLayer layer]; UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:self.bounds cornerRadius:self.rectRadius]; self.outLayer.strokeColor = self.fixedLineColor.CGColor; self.outLayer.lineWidth = _lineWidth; self.outLayer.fillColor = [UIColor clearColor].CGColor; self.outLayer.lineCap = kCALineCapRound; self.outLayer.path = path.CGPath; [self.layer addSublayer:self.outLayer]; self.progressLayer = [CAShapeLayer layer]; self.progressLayer.frame = self.bounds; self.progressLayer.fillColor = [UIColor clearColor].CGColor; self.progressLayer.strokeColor = self.actionLineColor.CGColor; self.progressLayer.lineWidth = _lineWidth; self.progressLayer.lineCap = kCALineCapRound; self.progressLayer.path = path.CGPath; [self.layer addSublayer:_progressLayer]; self.progress = 0; } return self; } - (void)willMoveToSuperview:(UIView *)newSuperview{ if (self.isAnimated) { _animatedTimer = [NSTimer scheduledTimerWithTimeInterval:_timeInterval target:self selector:@selector(animation) userInfo:nil repeats:YES]; [_animatedTimer fire]; [[NSRunLoop mainRunLoop] addTimer:_animatedTimer forMode:NSRunLoopCommonModes]; } } - (void)removeFromSuperview{ [super removeFromSuperview]; [_animatedTimer invalidate]; _animatedTimer = nil; LogFunc; } - (void)dealloc{ LogFunc; } - (void)animation{ __weak typeof(self) weakSelf = self; CGRect tempF = weakSelf.myFaceView.frame; tempF.origin.y = 2 * _myFaceViewInset - _myFaceViewInset * 0.5; [UIView animateWithDuration:weakSelf.timeInterval * 0.5 animations:^{ weakSelf.myFaceView.frame = tempF; } completion:^(BOOL finished) { CGRect tempF_= weakSelf.myFaceView.frame; tempF_.origin.y = weakSelf.myFaceViewInset * 0.5; [UIView animateWithDuration:weakSelf.timeInterval * 0.5 animations:^{ weakSelf.myFaceView.frame = tempF_; }]; }]; } - (void)setActionLineColor:(UIColor *)actionLineColor{ _actionLineColor = actionLineColor; self.progressLayer.strokeColor = self.actionLineColor.CGColor; } - (void)setFixedLineColor:(UIColor *)fixedLineColor{ _fixedLineColor = fixedLineColor; self.outLayer.strokeColor = self.fixedLineColor.CGColor; } - (void)setProgress:(CGFloat)progress{ if (progress<0) { progress = 0; } if (progress>1) { progress = 1; } _progress = progress; self.progressLayer.strokeEnd = progress; } - (void)layoutSubviews{ [super layoutSubviews]; _myFaceView.frame = CGRectInset(self.bounds, _myFaceViewInset, _myFaceViewInset); }
我把源码上传到了GitHub,大家下载之后可以直接使用,非常方便。地址在这 https://github.com/CoderPaulYin/YXProgressView.git
基本的使用举例:
_myProgressView = [[YXProgressView alloc] initWithFrame:CGRectMake(0, 100, 80, 80)]; _myProgressView.centerX = self.view.centerX; _myProgressView.actionLineColor = [UIColor greenColor];//设置进度条的填充颜色,也可以设置其他颜色 [self.view addSubview:_myProgressView];
然后在其他需要更新进度的地方:
- (void)sliderValueChanged:(UISlider *)sender{ NSLog(@"%f",sender.value); _myProgressView.progress = sender.value; }
我的QQ:82154139 GitHub: https://github.com/CoderPaulYin
欢迎加我好友交流,互相学习。