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

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

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

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

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

CAShapeLayer *layer = [CAShapeLayer new];
    layer.lineWidth = 10;//这里是layer的宽度
    //圆环的颜色
    layer.strokeColor = [UIColor redColor].CGColor;
    //背景填充色
    layer.fillColor = [UIColor clearColor].CGColor;
    //设置半径为10
    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];

 [path closePath];//在下面这行代码前加这个方法是封闭的图形
   layer.path = [path CGPath];//把贝塞尔画的路径赋值给图形层

//[path closePath];//这里加是开放的图形
    [self.view.layer addSublayer:layer];//添加到父图层

 

第一步 创建一个圆环

第二步 添加渐变颜色

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

第四部进一步包装

代码如下:

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

第二步添加渐变色:

 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;
    //设置半径为10
    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]];
    gradientLayer.startPoint = CGPointMake(0, 0);
    gradientLayer.endPoint = CGPointMake(1, 1);
    [view.layer addSublayer:gradientLayer];

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

 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;//用于保存_dotView的frame
    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);
    //更新圆环的frame
    CGRect rect = _redDot.frame;
    rect.origin.x = x;
    rect.origin.y = y;
    return  rect;
}

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值