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

    xiaoxiao2022-07-03  116

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

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

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

    贝塞尔曲线只是规划了一个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)