IOS使用progssview仿滴滴打車圓形計時_IOS

來源:互聯網
上載者:User

實作類別似在微信中使用的滴滴打車的progressview,實現效果如圖

//// CCProgressView.h// HurricaneConsumer//// Created by wangcong on 15-3-25.// Copyright (c) 2015年 WangCong. All rights reserved.// #import <UIKit/UIKit.h>#import <QuartzCore/QuartzCore.h> /** * 動畫開始 */typedef void(^block_progress_start)(); /** * 動畫進行中 * @param NSTimeInterval */typedef void(^block_progress_animing)(NSTimeInterval); /** * 動畫結束 */typedef void(^block_progress_stop)(); @interface CCProgressView : UIView{  NSTimeInterval _animationTime;} @property (nonatomic, strong) UILabel *centerLabel;    // 中心Label @property (nonatomic, copy) block_progress_start start;   // 動畫開始回調@property (nonatomic, copy) block_progress_animing animing; // 動畫進行@property (nonatomic, copy) block_progress_stop stop;    // 動畫結束回調 - (void) setAnimationTime:(NSTimeInterval)animationTime; - (void)startAnimation; - (void)stopAnimation; @end  //// CCProgressView.m// HurricaneConsumer//// Created by wangcong on 15-3-25.// Copyright (c) 2015年 WangCong. All rights reserved.// #import "CCProgressView.h" #define kProgressThumbWh 30 // 計時器間隔時間長度#define kAnimTimeInterval 0.1 /** * 圓圈layer上旋轉的layer */@interface CCProgressThumb : CALayer{  NSTimeInterval _animationTime;} @property (assign, nonatomic) double startAngle;@property (nonatomic, strong) UILabel *timeLabel;      // 顯示時間Label @end @implementation CCProgressThumb - (instancetype)init{  if ((self = [super init])) {    [self setupLayer];  }  return self;} - (void)layoutSublayers{  _timeLabel.frame = self.bounds;     [_timeLabel sizeToFit];  _timeLabel.center = CGPointMake(CGRectGetMidX(self.bounds) - _timeLabel.frame.origin.x,                  CGRectGetMidY(self.bounds) - _timeLabel.frame.origin.y);} - (void)setupLayer{  // 繪製圓  UIGraphicsBeginImageContext(CGSizeMake(kProgressThumbWh, kProgressThumbWh));  CGContextRef ctx = UIGraphicsGetCurrentContext();  CGContextSetLineWidth(ctx, 1);  CGContextSetFillColorWithColor(ctx, [UIColor lightGrayColor].CGColor);  CGContextSetStrokeColorWithColor(ctx, [UIColor lightGrayColor].CGColor);  CGContextAddEllipseInRect(ctx, CGRectMake(1, 1, kProgressThumbWh - 2, kProgressThumbWh - 2));  CGContextDrawPath(ctx, kCGPathFillStroke);  UIImage *circle = UIGraphicsGetImageFromCurrentImageContext();  UIGraphicsEndImageContext();     UIImageView *circleView = [[UIImageView alloc] initWithImage:circle];  circleView.frame = CGRectMake(0, 0, kProgressThumbWh, kProgressThumbWh);  circleView.image = circle;  [self addSublayer:circleView.layer];     _timeLabel = [[UILabel alloc] initWithFrame:self.bounds];  _timeLabel.textColor = [UIColor redColor];  _timeLabel.font = [UIFont systemFontOfSize:10];  _timeLabel.textAlignment = NSTextAlignmentCenter;  _timeLabel.text = @"00:00";  [self addSublayer:_timeLabel.layer];     _startAngle = - M_PI / 2;} - (void)setAnimationTime:(NSTimeInterval)animationTime{  _animationTime = animationTime;} - (double)calculatePercent:(NSTimeInterval)fromTime toTime:(NSTimeInterval)toTime{  double progress = 0.0f;  if ((toTime > 0) && (fromTime > 0)) {    progress = fromTime / toTime;    if ((progress * 100) > 100) {      progress = 1.0f;    }  }  return progress;} - (void)startAnimation{  CAKeyframeAnimation *pathAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position"];  pathAnimation.calculationMode = kCAAnimationPaced;  pathAnimation.fillMode = kCAFillModeForwards;  pathAnimation.removedOnCompletion = YES;  pathAnimation.duration = kAnimTimeInterval;  pathAnimation.repeatCount = 0;  pathAnimation.autoreverses = YES;     CGMutablePathRef arcPath = CGPathCreateMutable();  CGPathAddPath(arcPath, NULL, [self bezierPathFromParentLayerArcCenter]);  pathAnimation.path = arcPath;  CGPathRelease(arcPath);  [self addAnimation:pathAnimation forKey:@"position"];} /** * 根據父Layer擷取到一個移動路徑 * @return */- (CGPathRef)bezierPathFromParentLayerArcCenter{  CGFloat centerX = CGRectGetWidth(self.superlayer.frame) / 2.0;  CGFloat centerY = CGRectGetHeight(self.superlayer.frame) / 2.0;  double tmpStartAngle = _startAngle;  _startAngle = _startAngle + (2 * M_PI) * kAnimTimeInterval / _animateTime;  return [UIBezierPath bezierPathWithArcCenter:CGPointMake(centerX, centerY)                     radius:centerX                   startAngle:tmpStartAngle                    endAngle:_startAngle                    clockwise:YES].CGPath;} - (void)stopAnimation{  [self removeAllAnimations];} - (void)dealloc{  [[NSNotificationCenter defaultCenter] removeObserver:self];} @end /** * 圓圈layer */@interface CCProgress : CAShapeLayer{  NSTimeInterval _animationTime;} @property (assign, nonatomic) double initialProgress;@property (nonatomic) NSTimeInterval elapsedTime;                   //已使用時間@property (assign, nonatomic) double percent;@property (nonatomic, strong) UIColor *circleColor;@property (nonatomic, strong) CAShapeLayer *progress;@property (nonatomic, strong) CCProgressThumb *thumb;@property (nonatomic, assign) CGRect frame; @end @implementation CCProgress - (instancetype) init{  if ((self = [super init])) {    [self setupLayer];  }  return self;} - (void)layoutSublayers{  self.path = [self bezierPathWithArcCenter];  self.progress.path = self.path;     self.thumb.frame = CGRectMake((320 - kProgressThumbWh) / 2.0f, 180, kProgressThumbWh, kProgressThumbWh);  [super layoutSublayers];} - (void)setupLayer{  // 繪製圓  self.path = [self bezierPathWithArcCenter];  self.fillColor = [UIColor clearColor].CGColor;  self.strokeColor = [UIColor colorWithRed:0.86f green:0.86f blue:0.86f alpha:0.4f].CGColor;  self.lineWidth = 2;     // 添加可以變動的捲軸  self.progress = [CAShapeLayer layer];  self.progress.path = self.path;  self.progress.fillColor = [UIColor clearColor].CGColor;  self.progress.strokeColor = [UIColor whiteColor].CGColor;  self.progress.lineWidth = 4;  self.progress.lineCap = kCALineCapSquare;  self.progress.lineJoin = kCALineCapSquare;  [self addSublayer:self.progress];     // 添加可以旋轉的ThumbLayer  self.thumb = [[CCProgressThumb alloc] init];  [self addSublayer:self.thumb];} /** * 得到bezier曲線路勁 * @return */- (CGPathRef)bezierPathWithArcCenter{  CGFloat centerX = CGRectGetWidth(self.frame) / 2.0;  CGFloat centerY = CGRectGetHeight(self.frame) / 2.0;  return [UIBezierPath bezierPathWithArcCenter:CGPointMake(centerX, centerY)                     radius:centerX                   startAngle:(- M_PI / 2)                    endAngle:(3 * M_PI / 2)                    clockwise:YES].CGPath;} - (void)setCircleColor:(UIColor *)circleColor{  self.progress.strokeColor = circleColor.CGColor;} - (void)setAnimtionTime:(NSTimeInterval)animtionTime{  _animationTime = animtionTime;  [self.thumb setAnimationTime:animtionTime];} - (void)setElapsedTime:(NSTimeInterval)elapsedTime{  _initialProgress = [self calculatePercent:_elapsedTime toTime:_animationTime];  _elapsedTime = elapsedTime;     self.progress.strokeEnd = self.percent;  [self startAnimation];} - (double)percent{  _percent = [self calculatePercent:_elapsedTime toTime:_animationTime];  return _percent;} - (double)calculatePercent:(NSTimeInterval)fromTime toTime:(NSTimeInterval)toTime{  double progress = 0.0f;  if ((toTime > 0) && (fromTime > 0)) {    progress = fromTime / toTime;    if ((progress * 100) > 100) {      progress = 1.0f;    }  }  return progress;} - (void)startAnimation{  CABasicAnimation *pathAnimation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];  pathAnimation.duration = kAnimTimeInterval;  pathAnimation.fromValue = @(self.initialProgress);  pathAnimation.toValue = @(self.percent);  pathAnimation.removedOnCompletion = YES;  [self.progress addAnimation:pathAnimation forKey:nil];     [self.thumb startAnimation];  self.thumb.timeLabel.text = [self stringFromTimeInterval:_elapsedTime shorTime:YES];} - (void)stopAnimation{  _elapsedTime = 0;  self.progress.strokeEnd = 0.0;  [self removeAllAnimations];  [self.thumb stopAnimation];} /** * 時間格式轉換 * @param interval NSTimeInterval * @param shortTime BOOL * @return */- (NSString *)stringFromTimeInterval:(NSTimeInterval)interval shorTime:(BOOL)shortTime{  NSInteger ti = (NSInteger)interval;  NSInteger seconds = ti % 60;  NSInteger minutes = (ti / 60) % 60;  NSInteger hours = (ti / 3600);  if (shortTime) {    return [NSString stringWithFormat:@"%02ld:%02ld", (long)hours, (long)seconds];  } else {    return [NSString stringWithFormat:@"%02ld:%02ld:%02ld", (long)hours, (long)minutes, (long)seconds];  }} @end @interface CCProgressView () @property (nonatomic, strong) CCProgress *progressLayer;@property (nonatomic, strong) NSTimer *timer; @end @implementation CCProgressView - (instancetype)init{  if ((self = [super init])) {    [self setupView];  }  return self;} - (instancetype)initWithFrame:(CGRect)frame{  if ((self = [super initWithFrame:frame])) {    [self setupView];  }  return self;} - (void)layoutSubviews{  [super layoutSubviews];  self.progressLayer.frame = self.bounds;     [self.centerLabel sizeToFit];  self.centerLabel.center = CGPointMake(self.center.x - self.frame.origin.x, self.center.y- self.frame.origin.y);} - (void)setupView{  self.backgroundColor = [UIColor clearColor];  self.clipsToBounds = false;     self.progressLayer = [[CCProgress alloc] init];  self.progressLayer.frame = self.bounds;  [self.layer addSublayer:self.progressLayer];     _centerLabel = [[UILabel alloc] initWithFrame:self.bounds];  _centerLabel.font = [UIFont systemFontOfSize:18];  _centerLabel.textAlignment = NSTextAlignmentCenter;  _centerLabel.textColor = [UIColor whiteColor];  _centerLabel.text = @"已推送至 3 家";  [self.layer addSublayer:_centerLabel.layer];} - (void)setAnimationTime:(NSTimeInterval)animationTime{  _animationTime = animationTime;  [self.progressLayer setAnimtionTime:animationTime];} - (void)startAnimation{  if (!_timer) {    _timer = [NSTimer timerWithTimeInterval:kAnimTimeInterval target:self selector:@selector(doTimerSchedule) userInfo:nil repeats:YES];    [[NSRunLoop currentRunLoop] addTimer:_timer forMode:NSRunLoopCommonModes];  }  self.progressLayer.elapsedTime = 0;  if (_start) _start();} - (void)doTimerSchedule{  self.progressLayer.elapsedTime = self.progressLayer.elapsedTime + kAnimTimeInterval;;  if (_animing) _animing(self.progressLayer.elapsedTime);     if (self.progressLayer.elapsedTime >= _animationTime) {    [self stopAnimation];  }} - (void)stopAnimation{  if (_stop) _stop();  if (_timer) {    [_timer invalidate];    _timer = nil;  }  [_progressLayer stopAnimation];} @end 使用執行個體_progressView = [[CCProgressView alloc] initWithFrame:CGRectMake((APP_WIDTH - 240) / 2.0f, (APP_HEIGHT - 240) / 2.0f, 240, 240)];  [_progressView setAnimationTime:60];  _progressView.start = ^() {    NSLog(@"開始");  };  _progressView.animing = ^ (NSTimeInterval currentTime) {    NSLog(@"進行中");  };  __block id weakSelf = self;  _progressView.stop = ^ () {    NSLog(@"結束");    [weakSelf dismiss];  };  [self addSubview:_progressView];     [_progressView startAnimation];

以上所述就是本文的全部內容了,希望大家能夠喜歡

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.