IOS中的循环进度条

我想创build一个如下的圆形进度条:

循环进度栏

我如何使用Objective-C和Cocoa来做到这一点?

我如何开始做这个工作是创build一个UIView和编辑drawRect,但我有点失落。 任何帮助将不胜感激。

谢谢!

基本的概念是使用UIBezierPath类对您有利。 你可以绘制弧线,达到你以后的效果。 我只有一个半小时左右的时间来解决这个问题,但我的尝试是在下面。

很简单,它只是在path上使用中风,但在这里我们走了。 您可以根据您的确切需要来修改/修改,但是进行弧倒计数的逻辑将非常相似。

在视图类中:

 @interface TestView () { CGFloat startAngle; CGFloat endAngle; } @end @implementation TestView - (id)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; if (self) { // Initialization code self.backgroundColor = [UIColor whiteColor]; // Determine our start and stop angles for the arc (in radians) startAngle = M_PI * 1.5; endAngle = startAngle + (M_PI * 2); } return self; } - (void)drawRect:(CGRect)rect { // Display our percentage as a string NSString* textContent = [NSString stringWithFormat:@"%d", self.percent]; UIBezierPath* bezierPath = [UIBezierPath bezierPath]; // Create our arc, with the correct angles [bezierPath addArcWithCenter:CGPointMake(rect.size.width / 2, rect.size.height / 2) radius:130 startAngle:startAngle endAngle:(endAngle - startAngle) * (_percent / 100.0) + startAngle clockwise:YES]; // Set the display for the path, and stroke it bezierPath.lineWidth = 20; [[UIColor redColor] setStroke]; [bezierPath stroke]; // Text Drawing CGRect textRect = CGRectMake((rect.size.width / 2.0) - 71/2.0, (rect.size.height / 2.0) - 45/2.0, 71, 45); [[UIColor blackColor] setFill]; [textContent drawInRect: textRect withFont: [UIFont fontWithName: @"Helvetica-Bold" size: 42.5] lineBreakMode: NSLineBreakByWordWrapping alignment: NSTextAlignmentCenter]; } 

对于视图控制器:

 @interface ViewController () { TestView* m_testView; NSTimer* m_timer; } @end - (void)viewDidLoad { // Init our view [super viewDidLoad]; m_testView = [[TestView alloc] initWithFrame:self.view.bounds]; m_testView.percent = 100; [self.view addSubview:m_testView]; } - (void)viewDidAppear:(BOOL)animated { // Kick off a timer to count it down m_timer = [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(decrementSpin) userInfo:nil repeats:YES]; } - (void)decrementSpin { // If we can decrement our percentage, do so, and redraw the view if (m_testView.percent > 0) { m_testView.percent = m_testView.percent - 1; [m_testView setNeedsDisplay]; } else { [m_timer invalidate]; m_timer = nil; } } 

我已经为iOS做了一个简单的库。 它基于UILabel类,因此您可以在进度条内显示任何内容,但也可以将其保留为空。

一旦初始化,您只有一行代码来设置进度:

[_myProgressLabel setProgress:(50/100))];

该库被命名为KAProgressLabel

我用魔法数字的例子(为了更好的理解):

  CAShapeLayer *circle = [CAShapeLayer layer]; circle.path = [UIBezierPath bezierPathWithArcCenter:CGPointMake(29, 29) radius:27 startAngle:-M_PI_2 endAngle:2 * M_PI - M_PI_2 clockwise:YES].CGPath; circle.fillColor = [UIColor clearColor].CGColor; circle.strokeColor = [UIColor greenColor].CGColor; circle.lineWidth = 4; CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"]; animation.duration = 10; animation.removedOnCompletion = NO; animation.fromValue = @(0); animation.toValue = @(1); animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear]; [circle addAnimation:animation forKey:@"drawCircleAnimation"]; [imageCircle.layer.sublayers makeObjectsPerformSelector:@selector(removeFromSuperlayer)]; [imageCircle.layer addSublayer:circle]; 

对于Swift使用这个,

 let circle = UIView(frame: CGRectMake(0,0, 100, 100)) circle.layoutIfNeeded() let centerPoint = CGPoint (x: circle.bounds.width / 2, y: circle.bounds.width / 2) let circleRadius : CGFloat = circle.bounds.width / 2 * 0.83 var circlePath = UIBezierPath(arcCenter: centerPoint, radius: circleRadius, startAngle: CGFloat(-0.5 * M_PI), endAngle: CGFloat(1.5 * M_PI), clockwise: true ) let progressCircle = CAShapeLayer() progressCircle.path = circlePath.CGPath progressCircle.strokeColor = UIColor.greenColor().CGColor progressCircle.fillColor = UIColor.clearColor().CGColor progressCircle.lineWidth = 1.5 progressCircle.strokeStart = 0 progressCircle.strokeEnd = 0.22 circle.layer.addSublayer(progressCircle) self.view.addSubview(circle) 

参考:见这里 。

你可以看看我的lib MBCircularProgressBar

Swift 3使用这个,

CAShapeLayer与animation:继续与Zaid Pathan和。

  let circle = UIView(frame: CGRect(x: 100, y: 100, width: 100, height: 100)) circle.layoutIfNeeded() var progressCircle = CAShapeLayer() let centerPoint = CGPoint (x: circle.bounds.width / 2, y: circle.bounds.width / 2) let circleRadius : CGFloat = circle.bounds.width / 2 * 0.83 let circlePath = UIBezierPath(arcCenter: centerPoint, radius: circleRadius, startAngle: CGFloat(-0.5 * M_PI), endAngle: CGFloat(1.5 * M_PI), clockwise: true ) progressCircle = CAShapeLayer () progressCircle.path = circlePath.cgPath progressCircle.strokeColor = UIColor.green.cgColor progressCircle.fillColor = UIColor.clear.cgColor progressCircle.lineWidth = 2.5 progressCircle.strokeStart = 0 progressCircle.strokeEnd = 1.0 circle.layer.addSublayer(progressCircle) let animation = CABasicAnimation(keyPath: "strokeEnd") animation.fromValue = 0 animation.toValue = 1.0 animation.duration = 5.0 animation.fillMode = kCAFillModeForwards animation.isRemovedOnCompletion = false progressCircle.add(animation, forKey: "ani") self.view.addSubview(circle)