使用CoreGraphics在iOS中创建圆形渐变进度条

使用CoreGraphics在iOS中创建圆形渐变进度条,ios,core-graphics,uibezierpath,Ios,Core Graphics,Uibezierpath,我想做这样的东西: float radius = CGRectGetWidth(rect)/2.0f - self.circleBorderWidth/2.0f; float angleOffset = 0; UIBezierPath *aPath = [UIBezierPath bezierPathWithArcCenter:CGPointMake(CGRectGetMidX(rect), CGRectGetMidY(rect))

我想做这样的东西:

    float radius = CGRectGetWidth(rect)/2.0f - self.circleBorderWidth/2.0f;
float angleOffset = 0;

UIBezierPath *aPath = [UIBezierPath bezierPathWithArcCenter:CGPointMake(CGRectGetMidX(rect), CGRectGetMidY(rect))
                                                     radius:radius
                                                 startAngle:-angleOffset
                                                   endAngle:(mCircleSegs + 1)/(float)kCircleSegs*M_PI*2 - angleOffset
                                                  clockwise:YES];

CGPathRef shape = CGPathCreateCopyByStrokingPath(aPath.CGPath, NULL, 3, kCGLineCapSquare, kCGLineJoinMiter, 1.0f);

CGContextRef ctx = UIGraphicsGetCurrentContext();
CGContextAddPath(ctx, shape);
CGContextClip(ctx);

AngleGradientLayer *angle = [[AngleGradientLayer alloc] init];
angle.colors = [NSArray arrayWithObjects:
                (id)[UIColor colorWithRed:0 green:0 blue:0 alpha:1].CGColor,
                (id)[UIColor colorWithRed:1 green:1 blue:1 alpha:1].CGColor,
                nil];


CGContextClipToRect(ctx, self.bounds);
[angle drawInContext:ctx];

[angle release];

我尝试使用如下核心图形制作:

    float radius = CGRectGetWidth(rect)/2.0f - self.circleBorderWidth/2.0f;
float angleOffset = 0;

UIBezierPath *aPath = [UIBezierPath bezierPathWithArcCenter:CGPointMake(CGRectGetMidX(rect), CGRectGetMidY(rect))
                                                     radius:radius
                                                 startAngle:-angleOffset
                                                   endAngle:(mCircleSegs + 1)/(float)kCircleSegs*M_PI*2 - angleOffset
                                                  clockwise:YES];

CGPathRef shape = CGPathCreateCopyByStrokingPath(aPath.CGPath, NULL, 3, kCGLineCapSquare, kCGLineJoinMiter, 1.0f);

CGContextRef ctx = UIGraphicsGetCurrentContext();
CGContextAddPath(ctx, shape);
CGContextClip(ctx);

AngleGradientLayer *angle = [[AngleGradientLayer alloc] init];
angle.colors = [NSArray arrayWithObjects:
                (id)[UIColor colorWithRed:0 green:0 blue:0 alpha:1].CGColor,
                (id)[UIColor colorWithRed:1 green:1 blue:1 alpha:1].CGColor,
                nil];


CGContextClipToRect(ctx, self.bounds);
[angle drawInContext:ctx];

[angle release];

但我想我走错了方向。看起来不像这个例子。CoreGraphics能画出这样的东西吗?怎么做?

您用作剪辑的贝塞尔路径似乎只是一个圆的一小部分,而在您显示的图像中,路径更复杂:一个圆的两个部分,由两条线连接,整个路径具有“环形”形状

这种方法应该是可行的,我用它作为一个具有相同外观的计时器。 虽然我没有直接使用,但我修改了它的
-(CGImageRef)newImageGradientInRect:(CGRect)rect
方法以返回UIImage。 但我必须将这个图像旋转+PI/2,因为巴甫洛夫梯度角度梯度是水平开始的

我使用UIImage,因为它是一个不会改变的背景,所以我在我的图层中保存了这个UIImage的一个实例,并在更新剪辑路径时绘制它

- (void)drawInContext:(CGContextRef)ctx
{

    UIBezierPath *currentPath = [self timerPath];
   // other drawing code for glow (shadow) and white stroke)
    CGContextAddPath(ctx, currentPath.CGPath);
    // clip !
    CGContextClip(ctx);
    CGContextDrawImage(ctx, self.bounds, _circularGradientImage.CGImage);

    //_circularGradientImage from modified newImageGradientInRect method.

}
以下是我得到的:


用作剪辑的贝塞尔路径似乎只是一个圆的一小部分,而在您显示的图像中,路径更复杂:一个圆的两部分,由两条线连接,整个路径具有“环形”形状

这种方法应该是可行的,我用它作为一个具有相同外观的计时器。 虽然我没有直接使用,但我修改了它的
-(CGImageRef)newImageGradientInRect:(CGRect)rect
方法以返回UIImage。 但我必须将这个图像旋转+PI/2,因为巴甫洛夫梯度角度梯度是水平开始的

我使用UIImage,因为它是一个不会改变的背景,所以我在我的图层中保存了这个UIImage的一个实例,并在更新剪辑路径时绘制它

- (void)drawInContext:(CGContextRef)ctx
{

    UIBezierPath *currentPath = [self timerPath];
   // other drawing code for glow (shadow) and white stroke)
    CGContextAddPath(ctx, currentPath.CGPath);
    // clip !
    CGContextClip(ctx);
    CGContextDrawImage(ctx, self.bounds, _circularGradientImage.CGImage);

    //_circularGradientImage from modified newImageGradientInRect method.

}
以下是我得到的:


问题不在于圆的两个分数。问题是梯度的绘制。我真的不知道你怎么能用核心图形画出这样的东西。是的!但如上图所示,当进度条为20%、60%、80%时,。。。第一个分数的末尾总是最白的。因此,背景层不是解决方案。事实上,我想我们需要一个背景,是适应自身的进展…梯度也需要是透明的。在你的解决方案中,我看到一个很小的白色边框。我也有这样一个白色的边框。无论如何,我不知道如何删除它。我的示例中的白色边框是故意的:)您应该避免重新绘制可以通过单个变换完成的内容:在您的情况下,如果“全白色”总是在开头,请使用相同的渐变图像,应用旋转以适应当前进度…问题不在于圆的2个分数。问题是梯度的绘制。我真的不知道你怎么能用核心图形画出这样的东西。是的!但如上图所示,当进度条为20%、60%、80%时,。。。第一个分数的末尾总是最白的。因此,背景层不是解决方案。事实上,我想我们需要一个背景,是适应自身的进展…梯度也需要是透明的。在你的解决方案中,我看到一个很小的白色边框。我也有这样一个白色的边框。我不知道如何删除它。我的例子中的白色边框是故意的:)你应该避免重新绘制可以通过单个变换完成的内容:在你的例子中,如果“全白色”总是在开始时,请使用相同的渐变图像,应用旋转以适应当前的进度。。。