284 lines
10 KiB
Objective-C
284 lines
10 KiB
Objective-C
//
|
|
// 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
|