大佬教程收集整理的这篇文章主要介绍了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属性来控制绘制的进度.
如果你在这里看到我的答案,可以用两个圆圈和一些线条来简化绘制轮廓: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 – 根据百分比用渐变颜色填充圆环.所遇到的程序开发问题。
如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。