iOS UIBezierPath 通过贝塞尔曲线画圆环 创建一个环形进度指示器

参考 :http://blog.csdn.net/u013282507/article/details/50247001

一、先简单了解一下通过贝塞尔曲线画一个圆的基本概念,坐标系请参考下图。



要画一个贝塞尔曲线要有几个基本的要素

起始角度、结束角度、半径、是否按照顺时针方向

贝塞尔曲线只是规划了一个Layer的路径,而不能真正的展示出来,所以要和CAShapeLayer搭配使用,请看例子:

[objc]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. CAShapeLayer *layer = [CAShapeLayer new];  
  2. layer.lineWidth = 10;  
  3. //圆环的颜色  
  4. layer.strokeColor = [UIColor redColor].CGColor;  
  5. //背景填充色  
  6. layer.fillColor = [UIColor clearColor].CGColor;  
  7. //设置半径为10  
  8. CGFloat radius = 100;  
  9. //按照顺时针方向  
  10. BOOL clockWise = true;  
  11. //初始化一个路径  
  12. UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:self.view.center radius:radius startAngle:(1.25*M_PI) endAngle:1.75f*M_PI clockwise:clockWise];  
  13. layer.path = [path CGPath];  
  14. [self.view.layer addSublayer:layer];  
左图代表从从1.25π到1.75π的顺时针的圆弧,半径为100,宽度为10;

右图为clockWise设为false后的效果,路径变为逆时针


------------------------割-----------------------------------

下面进行实战开发:

目标效果如下


第一步 创建一个圆环

第二步 添加渐变颜色

第三步添加进度末尾的小红点

第四部进一步包装

代码如下:


第一步上面说过了,这里不做赘述


第二步添加渐变色:

渐变色讲解:

  iOS CAGradientLayer 实现渐变色


下面是设置渐变色的圆环代码

[objc]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. _lineWidth = 10.0f;  
  2.    
  3.  CGFloat viewWidth = 200;  
  4.  UIView *view = [[UIView alloc] initWithFrame:CGRectMake(00, viewWidth, viewWidth)];  
  5.  view.center = self.view.center;  
  6.  [self.view addSubview:view];  
  7.  _backView = view;  
  8.    
  9.  CAShapeLayer *layer = [CAShapeLayer new];  
  10.  layer.lineWidth = 10;  
  11.  //圆环的颜色  
  12.  layer.strokeColor = [UIColor redColor].CGColor;  
  13.  //背景填充色  
  14.  layer.fillColor = [UIColor clearColor].CGColor;  
  15.  //指定线的边缘是圆的  
  16.  layer.lineCap = kCALineCapRound;  
  17.  //设置半径为10  
  18.  CGFloat radius = viewWidth/2.0f - layer.lineWidth/2.0f;  
  19.  //按照顺时针方向  
  20.  BOOL clockWise = true;  
  21.  //初始化一个路径  
  22.  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];  
  23.  layer.path = [path CGPath];  
  24.  _layer = layer;  
  25.    
  26.  //设置渐变颜色  
  27.  CAGradientLayer *gradientLayer =  [CAGradientLayer layer];  
  28.  gradientLayer.frame = view.bounds;  
  29.  [gradientLayer setColors:[NSArray arrayWithObjects:(id)[RGB(13948164) CGColor],(id)[RGB(61189255) CGColor],(id)[RGB(3718282) CGColor], nil nil]];  
  30.  gradientLayer.startPoint = CGPointMake(00);  
  31.  gradientLayer.endPoint = CGPointMake(11);  
  32.  [view.layer addSublayer:gradientLayer];  
  33.  [gradientLayer setMask:layer];  

第三步:添加终点位置的红点

具体思路请查看:


  iOS 获取圆环终点位置的坐标方法 (UIBezierPath 终点位置)

代码如下:

[objc]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. -(void)addRedDot  
  2. {  
  3.     _redDot = [[UIView alloc] initWithFrame:CGRectMake(002020)];  
  4.     _redDot.layer.cornerRadius = 10.0f;  
  5.     _redDot.backgroundColor = [UIColor redColor];  
  6.     _redDot.frame = [self getEndPointFrameWithProgress:0.8f];  
  7.     [_backView addSubview:_redDot];  
  8. }  


[objc]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. //更新小点的位置  
  2. -(CGRect)getEndPointFrameWithProgress:(float)progress  
  3. {  
  4.     CGFloat angle = M_PI*2.0*progress;//将进度转换成弧度  
  5.     float radius = (_backView.bounds.size.width-_lineWidth)/2.0;//半径  
  6.     int index = (angle)/M_PI_2;//用户区分在第几象限内  
  7.     float needAngle = angle - index*M_PI_2;//用于计算正弦/余弦的角度  
  8.     float x = 0,y = 0;//用于保存_dotView的frame  
  9.     switch (index) {  
  10.         case 0:  
  11.             NSLog(@"第一象限");  
  12.             x = radius + sinf(needAngle)*radius;  
  13.             y = radius - cosf(needAngle)*radius;  
  14.             break;  
  15.         case 1:  
  16.             NSLog(@"第二象限");  
  17.             x = radius + cosf(needAngle)*radius;  
  18.             y = radius + sinf(needAngle)*radius;  
  19.             break;  
  20.         case 2:  
  21.             NSLog(@"第三象限");  
  22.             x = radius - sinf(needAngle)*radius;  
  23.             y = radius + cosf(needAngle)*radius;  
  24.             break;  
  25.         case 3:  
  26.             NSLog(@"第四象限");  
  27.             x = radius - cosf(needAngle)*radius;  
  28.             y = radius - sinf(needAngle)*radius;  
  29.             break;  
  30.               
  31.         default:  
  32.             break;  
  33.     }  
  34.     //为了让圆圈的中心和圆环的中心重合  
  35.     x -= (_redDot.bounds.size.width/2.0f - _lineWidth/2.0f);  
  36.     y -= (_redDot.bounds.size.width/2.0f - _lineWidth/2.0f);  
  37.     //更新圆环的frame  
  38.     CGRect rect = _redDot.frame;  
  39.     rect.origin.x = x;  
  40.     rect.origin.y = y;  
  41.     return  rect;  
  42. }  


经过这几步就可以得到想要的效果了,通过额外额修饰就可以得到一个通过圆环显示的进度指示器了;


Demo如下

☞  Demo

GitHub项目

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值