// // MaskTimeCircularProgressView.m // GIGA // // Created by lianxiang on 2018/9/3. // Copyright © 2018年 com.giga.ios. All rights reserved. // #import "MaskTimeCircularProgressView.h" #import "LXCountTimer.h" #import "SHineLabel.h" @interface MaskTimeCircularProgressView() @property (nonatomic) CADisplayLink *displayLink; @property (nonatomic) CAShapeLayer *progressLayer; @property (nonatomic) float progress; @property (nonatomic) CGFloat angle; @property (nonatomic) NSTimeInterval currentTimeinterval; @property (nonatomic,strong) LXCountTimer *timer; @property (nonatomic,strong) NSTimer *playTimer; @property (nonatomic,strong) UIImageView *holderImageView; @end @implementation MaskTimeCircularProgressView - (id)initWithFrame:(CGRect)frame backColor:(UIColor *)backColor progressColor:(UIColor *)progressColor lineWidth:(CGFloat)lineWidth timeinterval:(NSTimeInterval)timeinterval { self = [super initWithFrame:frame]; if (self) { _backColor = backColor; _progressColor = progressColor; self.lineWidth = lineWidth; self.timeinterval = timeinterval; [self setUP]; } return self; } - (id)initWithCoder:(NSCoder *)aDecoder{ self = [super initWithCoder:aDecoder]; if (self) { [self setUP]; } return self; } -(void)setUP{ self.backgroundColor = [UIColor clearColor]; self.holderImageView.frame = CGRectMake(self.frame.size.width/2 -self.frame.size.width/4 , self.frame.size.width/2 -self.frame.size.width/4,self.frame.size.width/2, self.frame.size.width/2); self.holderImageView.contentMode = UIViewContentModeScaleAspectFit; [self addSubview:self.holderImageView]; _currentTimeinterval = 0; _isMoving = NO; self.countLabel.frame = CGRectMake(_lineWidth, self.frame.size.height /2 - 15 , self.frame.size.width - _lineWidth*2, 30); [self addSubview:self.countLabel]; UILabel *minlabel = [[UILabel alloc] init]; minlabel.frame = CGRectMake(CGRectGetMidX(self.countLabel.frame) - (18/2) , CGRectGetMaxY(self.countLabel.frame) + 8, 18, 14); minlabel.text = @"min"; minlabel.textColor = [UIColor whiteColor]; minlabel.font = [UIFont fontWithName:GIGA_FONTNAME size:10]; [self addSubview:minlabel]; } -(LXCountTimer *)timer{ if (!_timer) { _timer = [[LXCountTimer alloc] init]; } return _timer; } - (NSTimer *)playTimer{ if (!_playTimer) { _playTimer = [NSTimer scheduledTimerWithTimeInterval:0.01 target:self selector:@selector(payCircular) userInfo:nil repeats:YES]; } return _playTimer; } //倒计时label -(SHineLabel *)countLabel{ if (!_countLabel) { _countLabel = [[SHineLabel alloc] init]; _countLabel.outLineColor = [UIColor whiteColor]; _countLabel.blurColor = [UIColor whiteColor]; _countLabel.oinsideColor = [UIColor whiteColor]; _countLabel.text = @"00:00"; _countLabel.fontsize = 22; _countLabel.font = [UIFont fontWithName:GIGA_FONTBOLD size:22]; } return _countLabel; } //停止图片 - (UIImageView *)holderImageView{ if (!_holderImageView) { _holderImageView = [[UIImageView alloc] init]; _holderImageView.image = [UIImage imageNamed:@"bg_on"]; } return _holderImageView; } - (void)setLineWidth:(CGFloat)lineWidth{ CAShapeLayer *backgroundLayer = [self createRingLayerWithCenter:CGPointMake(CGRectGetWidth(self.frame) / 2, CGRectGetHeight(self.frame) / 2) radius:CGRectGetWidth(self.bounds) / 2 - lineWidth / 2 lineWidth:lineWidth color:self.backColor]; _lineWidth = lineWidth; [self.layer addSublayer:backgroundLayer]; _progressLayer = [self createRingLayerWithCenter:CGPointMake(CGRectGetWidth(self.frame) / 2, CGRectGetHeight(self.frame) / 2) radius:CGRectGetWidth(self.bounds) / 2 - lineWidth / 2 lineWidth:lineWidth color:self.progressColor]; _progressLayer.strokeEnd = 0; [self.layer addSublayer:_progressLayer]; //渐变色 CGFloat width = self.frame.size.width; CGFloat height = self.frame.size.height; CALayer *gradientLayer = [CALayer layer]; gradientLayer.frame = self.bounds; CAGradientLayer *gradientLayer1 = [CAGradientLayer layer]; gradientLayer1.frame = CGRectMake(0, 0, width, height); gradientLayer1.colors = @[(__bridge id) [UIColor colorWithRed:255/255.0 green:107/255.0 blue:107/255.0 alpha:1/1.0].CGColor,(__bridge id)[UIColor colorWithRed:187/255.0 green:79/255.0 blue:253/255.0 alpha:1/1.0].CGColor]; //纵向变化 gradientLayer1.startPoint = CGPointMake(0.5, 0); gradientLayer1.endPoint = CGPointMake(0.5, 1); [gradientLayer addSublayer:gradientLayer1]; [self.layer addSublayer:gradientLayer]; gradientLayer.mask = _progressLayer ; } - (CAShapeLayer *)createRingLayerWithCenter:(CGPoint)center radius:(CGFloat)radius lineWidth:(CGFloat)lineWidth color:(UIColor *)color { UIBezierPath *smoothedPath = [UIBezierPath bezierPathWithArcCenter:CGPointMake(radius, radius) radius:radius startAngle:- M_PI_2 endAngle:(M_PI + M_PI_2) clockwise:YES]; CAShapeLayer *slice = [CAShapeLayer layer]; slice.contentsScale = [[UIScreen mainScreen] scale]; slice.frame = CGRectMake(center.x - radius, center.y - radius, radius * 2, radius * 2); slice.fillColor = [UIColor clearColor].CGColor; slice.strokeColor = color.CGColor; slice.lineWidth = lineWidth; slice.lineCap = kCALineJoinRound; slice.lineJoin = kCALineJoinBevel; slice.path = smoothedPath.CGPath; return slice; } - (void)setProgress:(float)progress{ if (progress == 0) { self.progressLayer.hidden = YES; dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ self.progressLayer.strokeEnd = 0; }); }else { self.progressLayer.hidden = NO; self.progressLayer.strokeEnd = progress; } } - (void)updateProgressCircle{ //update progress value self.progress = (float) (self.currentTimeinterval / self.timeinterval); if (self.delegate && [self.delegate conformsToProtocol:@protocol(MaskCirCularProGressViewDelegate)]) { //self.countLabel.text = [NSString stringWithFormat:@"%02ld:%02ld",minute,second]; [self.delegate updateProgressViewWith:self.currentTimeinterval]; } } -(void)payCircular{ self.currentTimeinterval += 0.01; } - (void)startWith:(NSTimeInterval)time{ self.timeinterval = time; [self countDown:time]; [self start]; } -(void)start{ [[NSRunLoop mainRunLoop] addTimer:self.playTimer forMode:NSRunLoopCommonModes]; if (!self.isMoving) { if (!self.displayLink) { self.displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(updateProgressCircle)]; [self.displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes]; }else { self.displayLink.paused = NO; } self.isMoving = YES; } } -(void)countDown:(NSTimeInterval)timeInterVal{ NSString *timeformat = [GiGaHelper stringWithNSTimerinterval:timeInterVal]; NSArray *timesArr = [timeformat componentsSeparatedByString:@":"]; NSString *hour = timesArr[0]; NSString *min = timesArr[1]; NSString *sec = timesArr[2]; [self countTimeBegain:hour.integerValue minute:min.integerValue second:sec.integerValue]; } #pragma mark 开始计时 -(void)countTimeBegain:(NSUInteger)hour minute:(NSUInteger)minute second:(NSUInteger)second{ long nowTimestamp = [GiGaHelper getNowDateTimestamp]; long futrueTimestamp = [GiGaHelper getFutureTimetstamp:hour minute:minute second:second]; weakify(self); [self.timer countDownWithStratTimeStamp:nowTimestamp finishTimeStamp:futrueTimestamp completeBlock:^(NSInteger day, NSInteger hour, NSInteger minute, NSInteger second) { [weakSelf refreshTimeCount:hour minute:minute second:second]; }]; } -(void)refreshTimeCount:(NSInteger)hour minute:(NSInteger)minute second:(NSInteger)second{ self.countLabel.text = [NSString stringWithFormat:@"%02ld:%02ld",minute,second]; if (hour == 0 && minute == 0 && second == 0) { [self.timer destoryTimer]; [self.playTimer invalidate]; self.playTimer = nil; [self stop]; if (self.delegate && [self.delegate conformsToProtocol:@protocol(MaskCirCularProGressViewDelegate)]) { [self.delegate progressDidFish]; } } } -(void)pasuse{ if (self.isMoving) { self.displayLink.paused = YES; self.isMoving = NO; } } -(void)stop{ self.isMoving = NO; self.progress = 0 ; self.currentTimeinterval = 0; [self.displayLink invalidate]; self.displayLink = nil; [self.timer destoryTimer]; [self.playTimer invalidate]; self.playTimer = nil; } //calculate angle between start to point - (CGFloat)angleFromStartToPoint:(CGPoint)point{ CGFloat angle = [self angleBetweenLinesWithLine1Start:CGPointMake(CGRectGetWidth(self.bounds) / 2,CGRectGetHeight(self.bounds) / 2) Line1End:CGPointMake(CGRectGetWidth(self.bounds) / 2,CGRectGetHeight(self.bounds) / 2 - 1) Line2Start:CGPointMake(CGRectGetWidth(self.bounds) / 2,CGRectGetHeight(self.bounds) / 2) Line2End:point]; if (CGRectContainsPoint(CGRectMake(0, 0, CGRectGetWidth(self.frame) / 2, CGRectGetHeight(self.frame)), point)) { angle = 2 * M_PI - angle; } return angle; } //calculate angle between 2 lines - (CGFloat)angleBetweenLinesWithLine1Start:(CGPoint)line1Start Line1End:(CGPoint)line1End Line2Start:(CGPoint)line2Start Line2End:(CGPoint)line2End{ CGFloat a = line1End.x - line1Start.x; CGFloat b = line1End.y - line1Start.y; CGFloat c = line2End.x - line2Start.x; CGFloat d = line2End.y - line2Start.y; return acos(((a * c) + (b * d)) / ((sqrt(a * a + b * b)) * (sqrt(c * c + d * d)))); } @end