ios – 根据百分比用渐变颜色填充圆环.

ios – 根据百分比用渐变颜色填充圆环.,第1张

概述寻找我的问题的解决方案,我必须在环中填充颜色. 我可以用我的代码填充一个颜色,但我遇到了一些问题 >使用此代码,我无法找到如何在圆圈中填充所需的颜色数量,即20%,40%,70%等. >当我给出渐变色时,它不是如图所示. 我正在使用的代码: int radius = 130;CAShapeLayer *arc = [CAShapeLayer layer];arc.path = [UIBezi 寻找我的问题的解决方案,我必须在环中填充颜色.
我可以用我的代码填充一个颜色,但我遇到了一些问题

>使用此代码,我无法找到如何在圆圈中填充所需的颜色数量,即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属性来控制绘制的进度.

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

.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 – 根据百分比用渐变颜色填充圆环.所遇到的程序开发问题。

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

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/web/1055451.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-25
下一篇 2022-05-25

发表评论

登录后才能评论

评论列表(0条)

保存