HTML5   发布时间:2022-04-27  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了ios – 根据百分比用渐变颜色填充圆环.大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
寻找我的问题的解决方案,我必须在环中填充颜色.
我可以用我的代码填充一个颜色,但我遇到了一些问题

>使用此代码,我无法找到如何在圆圈中填充所需的颜色数量,即20%,40%,70%等.
>当我给出渐变色时,它不是如图所示.

我正在使用的代码

int radius = 130;

CAShapeLayer *arc = [CAShapeLayer layer];
arc.path = [UIBezierPath bezierPathWithArcCenter:CGPointMake(100,0) radius:radius startAngle:39.8 endAngle:19.9 clockwise:YES].CGPath;

arc.position = CGPointMake(CGRectGetMidX(self.framE)-radius,CGRectGetMidY(self.framE)-radius);

arc.fillColor = [UIColor clearColor].CGColor;
arc.strokeColor = [UIColor redColor].CGColor;
arc.lineWidth = 25;
CABasicAnimation *drawAnimation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];
drawAnimation.duration            = 5.0; // "animate over 10 seconds or so.."
drawAnimation.repeatCount         = 1.0;  // Animate only once..
drawAnimation.removedOnCompletion = NO;   // Remain stroked after the animation..
drawAnimation.fromValue = [NSnumber numberWithFloat:0.0f];
drawAnimation.toValue   = [NSnumber numberWithFloat:100.0f];
drawAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];
[arc addAnimation:drawAnimation forKey:@"drawCircleAnimation"];

CAGradientLayer *gradientLayer = [CAGradientLayer layer];
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
UIColor *gradientColor = [UIColor colorWithRed:0.51 green:0.0 blue:0.49 alpha:1.0];

NSArray *gradientColors = [NSArray arrayWithObjects:
                           (id)[UIColor blueColor].CGColor,(id)gradientColor.CGColor,(id)[UIColor redColor].CGColor,nil];
CGFloat gradientLOCATIOns[] = {0,0.5,1};
CGGradientRef gradient = CGGradientCreateWithColors(colorSpace,(CFArrayRef)gradientColors,gradientLOCATIOns);

gradientLayer.colors = (__bridge NSArray *)(gradient);

gradientLayer.startPoint = CGPointMake(0.0,0.7);
gradientLayer.endPoint = CGPointMake(1,-0.1);
[self.layer addSublayer:gradientLayer];
gradientLayer.mask = arc;

重要提示:颜色必须如图所示

我正在为这个问题寻找非常具体的答案.

在此之前,感谢所有有时间调查的人.

解决方法

要使用颜色填充圆的数量,您必须在填充图层的顶部绘制轮廓并仅剪切填充的图层.

为了使渐变跟随圆,您必须将其划分为多个分段线性渐变.由于您提供的图形已经有一些带轮廓的线段,我们可以使用这些轮廓来隐藏任何不完美的连接不同的渐变.

我举了一个例子,如果你想更多地控制颜色,你可以为CircleGradientLayer中的每个段设置它们.通过设置CircleProgressview的progress属性来控制绘制的进度.

如果你在这里看到我的答案,可以用两个圆圈和一些线条来简化绘制轮廓:@L_404_0@但是在编写此代码时,复制和粘贴速度更快;)

.h文件中没什么特别的,只是插入编译器想要的东西,我只在这里发布.m:

CircleProgressview

@implementation CircleProgressview{
    CircleGradientLayer *_gradientLayer;
    CircLeoutlineLayer *_outlineLayer;
}

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        self.BACkgroundColor = [UIColor clearColor];

        int numSegments = 7;
        CGFloat circleRadius = 130;
        CGFloat circleWidth = 30;

        NSDictionary *circleData = @{
                                    @"numberOfSegments":@(numSegments),@"circleRadius":@(circleRadius),@"circleWidth":@(circleWidth)
                                    };

        _gradientLayer = [CircleGradientLayer layer];
        _gradientLayer.contentsScale = 2;
        _gradientLayer.frame = self.bounds;
        [_gradientLayer setCircleData:circleData];
        [_gradientLayer setNeedsDisplay];
        [self.layer addSublayer:_gradientLayer];

        _outlineLayer = [CircLeoutlineLayer layer];
        _outlineLayer.frame = self.bounds;
        _outlineLayer.contentsScale = 2;
        [_outlineLayer setCircleData:circleData];
        [_outlineLayer setNeedsDisplay];
        [self.layer addSublayer:_outlineLayer];

        self.progress = 1;
    }
    return self;
}

- (void)setProgress:(CGFloat)progress{
    _progress = MAX(0,MIN(1,progress));
    _gradientLayer.progress = progress;
}

@end

CircleGradientLayer

@implementation CircleGradientLayer{
    int _numSegments;
    CGFloat _circleRadius;
    CGFloat _circleWidth;

    CAShapeLayer *_maskLayer;
}

+(id)layer{
    CircleGradientLayer *layer = [[CircleGradientLayer alloc] init];
    return layer;
}

-(void)setCircleData:(NSDictionary*)data{
    _numSegments = [data[@"numberOfSegments"] intValue];
    _circleRadius = [data[@"circleRadius"] doubleValue];
    _circleWidth = [data[@"circleWidth"] doubleValue];

    [self createMask];
}

- (void)createMask{
    _maskLayer = [CAShapeLayer layer];
    _maskLayer.frame = self.bounds;

    CGFloat angleStep = 2*M_PI/(_numSegments+1);
    CGFloat startAngle = angleStep/2 + M_PI_2;
    CGFloat endAngle = startAngle+_numSegments*angleStep+0.005; //add a bit that the outline is not clipped

    _maskLayer.path = [UIBezierPath bezierPathWithArcCenter:CGPointMake(CGRectGetMidX(self.bounds),CGRectGetMidY(self.bounds)) radius:_circleRadius startAngle:startAngle endAngle:endAngle clockwise:YES].CGPath;
    _maskLayer.fillColor = [UIColor clearColor].CGColor;
    _maskLayer.strokeColor = [UIColor redColor].CGColor;
    _maskLayer.lineWidth = 2*_circleWidth+2; //stroke is centered -> *2 to cover all

    self.mask = _maskLayer;
}

- (void)setProgress:(CGFloat)progress{
    _progress = MAX(0,progress));
    _maskLayer.strokeEnd = _progress;
}

-(void)drawInContext:(CGContextRef)ctx{
   // would get better gradient joints by not using antialias,but since they are hidden,it is not needed to adjust it     
   // CGContextSetAllowsAntialiasing(ctx,NO);

    UIGraphicsPushContext(ctX);

    //some values to adjust the circle
    UIColor *startColor = [UIColor colorWithRed:1 green:0 blue:21/255. alpha:1];
    UIColor *endColor = [UIColor colorWithRed:0 green:180/255. blue:35/255. alpha:1];

    CGPoint centerPoint = CGPointMake(CGRectGetMidX(self.bounds),CGRectGetMidY(self.bounds));

    //calculate startAngle and the increment between segements
    CGFloat angleStep = 2*M_PI/(_numSegments+1);
    CGFloat startAngle = angleStep/2 + M_PI_2;

    //convert colors to hsv
    CGFloat startHue,startSat,startBrightness,startAlpha;
    CGFloat endHue,endSat,endBrightness,endAlpha;
    [startColor getHue:&startHue saturation:&startSat brightness:&startBrightness alpha:&startAlpha];
    [endColor getHue:&endHue saturation:&endSat brightness:&endBrightness alpha:&endAlpha];
    if(endHue<startHuE)
        endHue+=1;


    //draw the segments
    for(int i=0;i<_numSegments;i++){
        //calcualte segment startColor
        CGFloat hue = startHue+((endHue-startHuE)*i)/_numSegments;
        if(hue>1)
            hue-=1;

        CGFloat brightness = startBrightness+((endBrightness-startBrightness)*i)/(_numSegments);
        if(_numSegments==7){
            //just increasing the brighness a bit to get more yellow like on your picture ;)
            brightness = i>3?startBrightness+((endBrightness-startBrightness)*(i-4))/(_numSegments-4):startBrightness;
        }
        UIColor *fromColor = [UIColor colorWithHue:hue saturation:startSat+((endSat-startSat)*i)/_numSegments brightness:brightness alpha:startAlpha+((endAlpha-startAlpha)*i)/_numSegments];

        //calculate segement endColor
        hue = startHue+((endHue-startHuE)*(i+1))/_numSegments;
        if(hue>1)
            hue-=1;
        brightness = startBrightness+((endBrightness-startBrightness)*i)/(_numSegments);
        if(_numSegments==7){
            brightness = i>3?startBrightness+((endBrightness-startBrightness)*(i-3))/(_numSegments-4):startBrightness;
        }

        UIColor *toColor = [UIColor colorWithHue:hue saturation:startSat+((endSat-startSat)*(i+1))/_numSegments brightness:brightness alpha:startAlpha+((endAlpha-startAlpha)*(i+1))/_numSegments];

        //actually draw the segment
        [self drawSegmentAtCenter:centerPoint from:startAngle to:startAngle+angleStep radius:_circleRadius width:_circleWidth startColor:fromColor endColor:toColor];

        startAngle+=angleStep;
    }

    //start clearing the inside
    CGContextSetBlendMode(UIGraphicsGetCurrentContext(),kCGBlendModeClear);

    UIBezierPath* innerPath = [UIBezierPath bezierPath];
    [innerPath moveToPoint:centerPoint];
    [innerPath addArcWithCenter:centerPoint radius:_circleRadius-_circleWidth-0.5 startAngle:0 endAngle:2*M_PI clockwise:YES];
    [innerPath fill];
}

- (void)drawSegmentAtCenter:(CGPoint)center from:(CGFloat)startAngle to:(CGFloat)endAngle radius:(CGFloat)radius width:(CGFloat)width startColor:(UIColor *)startColor endColor:(UIColor*)endColor{

    CGContextSaveGState(UIGraphicsGetCurrentContext());

    //apply a clip arc for the gradient
    UIBezierPath *path = [UIBezierPath bezierPath];
    [path moveToPoint:center];
    [path addArcWithCenter:center radius:radius startAngle:startAngle endAngle:endAngle clockwise:YES];
    [path addClip];


    //draw the gradient
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    CGFloat LOCATIOns[] = { 0.0,1.0 };
    NSArray *colors = @[(__bridge id) startColor.CGColor,(__bridge id) endColor.CGColor];
    CGGradientRef gradient = CGGradientCreateWithColors(colorSpace,(__bridge CFArrayRef) colors,LOCATIOns);

    CGPoint startPoint = CGPointMake(center.x-sinf(startAngle-M_PI_2)*radius,center.y+cosf(startAngle-M_PI_2)*radius);
    CGPoint endPoint = CGPointMake(center.x-sinf(endAngle-M_PI_2)*radius,center.y+cosf(endAngle-M_PI_2)*radius);
    CGContextDrawLinearGradient(UIGraphicsGetCurrentContext(),gradient,startPoint,endPoint,kCGGradientDrawsAfterEndLOCATIOn|kCGGradientDrawsBeforeStartLOCATIOn);

    CGGradientRelease(gradient);
    CGColorSpaceRelease(colorSpacE);

    CGContextRestoreGState(UIGraphicsGetCurrentContext());
}

@end

CircLeoutlineLayer

@implementation CircLeoutlineLayer{
    int _numSegments;
    CGFloat _circleradius;
    CGFloat _circlewidth;    
}

+(id)layer{
    CircLeoutlineLayer *layer = [[CircLeoutlineLayer alloc] init];
    return layer;
}

-(void)setCircleData:(NSDictionary*)data{
    _numSegments = [data[@"numberOfSegments"] intValue];
    _circleradius = [data[@"circleRadius"] doubleValue];
    _circlewidth = [data[@"circleWidth"] doubleValue];
}

-(void)drawInContext:(CGContextRef)ctx{
    UIGraphicsPushContext(ctX);

    //some values to adjust the circle
    [[UIColor colorWithWhite:130/255. alpha:1] setstroke]; //the outline color

    CGPoint centerPoint = CGPointMake(CGRectGetMidX(self.bounds),CGRectGetMidY(self.bounds));

    //calculate startAngle and the increment between segements
    CGFloat angleStep = 2*M_PI/(_numSegments+1);
    CGFloat startAngle = angleStep/2 + M_PI_2;

    //draw the segments
    for(int i=0;i<_numSegments;i++){
         //actually draw the segment
        [self drawSegmentAtCenter:centerPoint from:startAngle to:startAngle+angleStep radius:_circleradius width:_circlewidth doFill:NO];

        startAngle+=angleStep;
    }

    //draw an inner outline
    UIBezierPath *innerPath = [UIBezierPath bezierPath];
    [innerPath moveToPoint:centerPoint];
    [innerPath addArcWithCenter:centerPoint radius:_circleradius-_circlewidth startAngle:0 endAngle:2*M_PI clockwise:YES];
    [innerPath stroke];


    //start clearing the inside
    CGContextSetBlendMode(UIGraphicsGetCurrentContext(),kCGBlendModeClear);

    innerPath = [UIBezierPath bezierPath];
    [innerPath moveToPoint:centerPoint];
    [innerPath addArcWithCenter:centerPoint radius:_circleradius-_circlewidth-0.5 startAngle:0 endAngle:2*M_PI clockwise:YES];
    [innerPath fill];

    //also clear a whole segment at the bottom to get rid of the inner outline
    [self drawSegmentAtCenter:centerPoint from:-angleStep/2 + M_PI_2 to:angleStep/2+M_PI_2 radius:_circleradius width:_circlewidth doFill:YES];


    //redraw the outlines at begin and end of circle since beginning was just cleared and end-outline hasn't been drawed
    CGContextSetBlendMode(UIGraphicsGetCurrentContext(),kCGBlendModeNormal);

    CGPoint startPoint = CGPointMake(centerPoint.x+sinf(-angleStep/2)*(_circleradius),centerPoint.y+cosf(-angleStep/2)*(_circleradius));
    CGPoint endPoint = CGPointMake(centerPoint.x+sinf(-angleStep/2)*(_circleradius-_circlewidth),centerPoint.y+cosf(-angleStep/2)*(_circleradius-_circlewidth));
    CGContextSetLineWidth(UIGraphicsGetCurrentContext(),1);
    CGContextMoveToPoint(UIGraphicsGetCurrentContext(),startPoint.x,startPoint.y);
    CGContextAddLineToPoint(UIGraphicsGetCurrentContext(),endPoint.x,endPoint.y);
    CGContextstrokePath(UIGraphicsGetCurrentContext());

    startPoint = CGPointMake(centerPoint.x+sinf(angleStep/2)*(_circleradius),centerPoint.y+cosf(angleStep/2)*(_circleradius));
    endPoint = CGPointMake(centerPoint.x+sinf(angleStep/2)*(_circleradius-_circlewidth),centerPoint.y+cosf(angleStep/2)*(_circleradius-_circlewidth));
    CGContextMoveToPoint(UIGraphicsGetCurrentContext(),endPoint.y);
    CGContextstrokePath(UIGraphicsGetCurrentContext());
}

- (void)drawSegmentAtCenter:(CGPoint)center from:(CGFloat)startAngle to:(CGFloat)endAngle radius:(CGFloat)radius width:(CGFloat)width doFill:(BOOL)fill{

    UIBezierPath *path = [UIBezierPath bezierPath];
    [path moveToPoint:center];
    [path addArcWithCenter:center radius:radius startAngle:startAngle endAngle:endAngle clockwise:YES];
    if(fill)
        [path fill];
    [path stroke];

}

@end

大佬总结

以上是大佬教程为你收集整理的ios – 根据百分比用渐变颜色填充圆环.全部内容,希望文章能够帮你解决ios – 根据百分比用渐变颜色填充圆环.所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。