参考 :http://blog.csdn.net/u013282507/article/details/50247001
一、先简单了解一下通过贝塞尔曲线画一个圆的基本概念,坐标系请参考下图。
要画一个贝塞尔曲线要有几个基本的要素
起始角度、结束角度、半径、是否按照顺时针方向
贝塞尔曲线只是规划了一个Layer的路径,而不能真正的展示出来,所以要和CAShapeLayer搭配使用,请看例子:
- CAShapeLayer *layer = [CAShapeLayer new];
- layer.lineWidth = 10;
-
- layer.strokeColor = [UIColor redColor].CGColor;
-
- layer.fillColor = [UIColor clearColor].CGColor;
-
- CGFloat radius = 100;
-
- BOOL clockWise = true;
-
- UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:self.view.center radius:radius startAngle:(1.25*M_PI) endAngle:1.75f*M_PI clockwise:clockWise];
- layer.path = [path CGPath];
- [self.view.layer addSublayer:layer];
左图代表从从1.25π到1.75π的顺时针的圆弧,半径为100,宽度为10;
右图为clockWise设为false后的效果,路径变为逆时针
------------------------割-----------------------------------
下面进行实战开发:
目标效果如下
第一步 创建一个圆环
第二步 添加渐变颜色
第三步添加进度末尾的小红点
第四部进一步包装
代码如下:
第一步上面说过了,这里不做赘述
第二步添加渐变色:
渐变色讲解:
☞ iOS CAGradientLayer 实现渐变色
下面是设置渐变色的圆环代码
- _lineWidth = 10.0f;
-
- CGFloat viewWidth = 200;
- UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, viewWidth, viewWidth)];
- view.center = self.view.center;
- [self.view addSubview:view];
- _backView = view;
-
- CAShapeLayer *layer = [CAShapeLayer new];
- layer.lineWidth = 10;
-
- layer.strokeColor = [UIColor redColor].CGColor;
-
- layer.fillColor = [UIColor clearColor].CGColor;
-
- layer.lineCap = kCALineCapRound;
-
- CGFloat radius = viewWidth/2.0f - layer.lineWidth/2.0f;
-
- BOOL clockWise = true;
-
- UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:CGPointMake(viewWidth/2.0f, viewWidth/2.0f) radius:radius startAngle:(-0.5f*M_PI) endAngle:1.5f*M_PI clockwise:clockWise];
- layer.path = [path CGPath];
- _layer = layer;
-
-
- CAGradientLayer *gradientLayer = [CAGradientLayer layer];
- gradientLayer.frame = view.bounds;
- [gradientLayer setColors:[NSArray arrayWithObjects:(id)[RGB(139, 48, 164) CGColor],(id)[RGB(61, 189, 255) CGColor],(id)[RGB(37, 182, 82) CGColor], nil nil]];
- gradientLayer.startPoint = CGPointMake(0, 0);
- gradientLayer.endPoint = CGPointMake(1, 1);
- [view.layer addSublayer:gradientLayer];
- [gradientLayer setMask:layer];
第三步:添加终点位置的红点
具体思路请查看:
☞ iOS 获取圆环终点位置的坐标方法 (UIBezierPath 终点位置)
代码如下:
- -(void)addRedDot
- {
- _redDot = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 20, 20)];
- _redDot.layer.cornerRadius = 10.0f;
- _redDot.backgroundColor = [UIColor redColor];
- _redDot.frame = [self getEndPointFrameWithProgress:0.8f];
- [_backView addSubview:_redDot];
- }
-
- -(CGRect)getEndPointFrameWithProgress:(float)progress
- {
- CGFloat angle = M_PI*2.0*progress;
- float radius = (_backView.bounds.size.width-_lineWidth)/2.0;
- int index = (angle)/M_PI_2;
- float needAngle = angle - index*M_PI_2;
- float x = 0,y = 0;
- switch (index) {
- case 0:
- NSLog(@"第一象限");
- x = radius + sinf(needAngle)*radius;
- y = radius - cosf(needAngle)*radius;
- break;
- case 1:
- NSLog(@"第二象限");
- x = radius + cosf(needAngle)*radius;
- y = radius + sinf(needAngle)*radius;
- break;
- case 2:
- NSLog(@"第三象限");
- x = radius - sinf(needAngle)*radius;
- y = radius + cosf(needAngle)*radius;
- break;
- case 3:
- NSLog(@"第四象限");
- x = radius - cosf(needAngle)*radius;
- y = radius - sinf(needAngle)*radius;
- break;
-
- default:
- break;
- }
-
- x -= (_redDot.bounds.size.width/2.0f - _lineWidth/2.0f);
- y -= (_redDot.bounds.size.width/2.0f - _lineWidth/2.0f);
-
- CGRect rect = _redDot.frame;
- rect.origin.x = x;
- rect.origin.y = y;
- return rect;
- }
经过这几步就可以得到想要的效果了,通过额外额修饰就可以得到一个通过圆环显示的进度指示器了;
Demo如下
☞ Demo
GitHub项目