Desenhe parte de um círculo

Para um aplicativo para iPhone, quero desenhar um círculo, que é apenas para uma porcentagem x preenchida.

Algo assim:

texto alternativo

Não tenho problemas em calcular o raio, os graus ou os radianos, isso não é problema. Também desenhar o círculo já está feito. Mas como obtenho o iPhone SDK para desenhar a parte que está preenchida?

Eu posso desenhar um retângulo desse tamanho, mas não parte de um círculo.

Eu só quero desenhar isso em um contexto normal.

Espero que alguém possa me dar algumas dicas aqui.

Use as funções de arco do CGContext :

 CGContextAddArc(context, centerX, centerY, radius, startAngleRadians, endAngleRadians, clockwise ? 1 : 0); 

Veja a documentação para CGContextAddArc() .

Muitas pessoas mostraram como isso pode ser feito no Core Graphics, mas também pode ser feito com o Core Animation, que oferece a grande adição de poder animar facilmente a porcentagem do formato do bolo.

O código a seguir criará tanto o anel quanto as camadas parcialmente preenchidas (mesmo que você tenha dito que você já pode desenhar o anel), já que é bom ter o anel e o formato de pizza a serem desenhados usando o mesmo método.

Se você animar as propriedades strokeStart ou strokeEnd da camada pieShape, terá a porcentagem animada. Como acontece com todo o código do Core Animation, você precisará adicionar QuartzCore.framework ao seu projeto e include no seu código.

 // Create a white ring that fills the entire frame and is 2 points wide. // Its frame is inset 1 point to fit for the 2 point stroke width CGFloat radius = MIN(self.frame.size.width,self.frame.size.height)/2; CGFloat inset = 1; CAShapeLayer *ring = [CAShapeLayer layer]; ring.path = [UIBezierPath bezierPathWithRoundedRect:CGRectInset(self.bounds, inset, inset) cornerRadius:radius-inset].CGPath; ring.fillColor = [UIColor clearColor].CGColor; ring.strokeColor = [UIColor whiteColor].CGColor; ring.lineWidth = 2; // Create a white pie-chart-like shape inside the white ring (above). // The outside of the shape should be inside the ring, therefore the // frame needs to be inset radius/2 (for its outside to be on // the outside of the ring) + 2 (to be 2 points in). CAShapeLayer *pieShape = [CAShapeLayer layer]; inset = radius/2 + 2; // The inset is updated here pieShape.path = [UIBezierPath bezierPathWithRoundedRect:CGRectInset(self.bounds, inset, inset) cornerRadius:radius-inset].CGPath; pieShape.fillColor = [UIColor clearColor].CGColor; pieShape.strokeColor = [UIColor whiteColor].CGColor; pieShape.lineWidth = (radius-inset)*2; // Add sublayers // NOTE: the following code is used in a UIView subclass (thus self is a view) // If you instead chose to use this code in a view controller you should instead // use self.view.layer to access the view of your view controller. [self.layer addSublayer:ring]; [self.layer addSublayer:pieShape]; 

Tente isto:

 CGContextMoveToPoint(the center point) CGContextAddLineToPoint(the starting point of the fill path on the circumference) CGContextAddArcToPoint(the ending point of the fill path on the circumference) CGContextAddLineToPoint(the center point) CGContextFillPath 

Eu implementei uma visualização de progresso de torta que parece semelhante ao que você está fazendo. É open source. Espero que o código fonte ajude.

Fonte SSPieProgressView.h

Fonte SSPieProgressView.m

CircleViewController.h

 #import  @interface CircleViewController : UIViewController @end 

CircleViewController.m

 #import "CircleViewController.h" #import "GraphView.h" @interface CircleViewController () @end @implementation CircleViewController - (void)viewDidLoad { [super viewDidLoad]; GraphView *graphView = [[GraphView alloc] initWithFrame:CGRectMake(100, 100, 200, 200)]; graphView.backgroundColor = [UIColor whiteColor]; graphView.layer.borderColor = [UIColor redColor].CGColor; graphView.layer.borderWidth = 1.0f; [self.view addSubview:graphView]; } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } @end 

GraphView.h

 #import  @interface GraphView : UIView @end 

GraphView.m

 #import "GraphView.h" @implementation GraphView - (void)drawRect:(CGRect)rect { CGPoint circleCenter = CGPointMake(self.bounds.size.width / 2, self.bounds.size.height / 2); [self drawCircleWithCircleCenter:(CGPoint) circleCenter radius:80 firstColor:[UIColor blueColor].CGColor secondeColor:[UIColor redColor].CGColor lineWidth:2 startDegree:0 currentDegree:90]; //[self drawCircleWithCircleCenter2:(CGPoint) circleCenter radius:80 firstColor:[UIColor blueColor].CGColor secondeColor:[UIColor redColor].CGColor lineWidth:2 startDegree:0 currentDegree:90]; } - (void)drawCircleWithCircleCenter:(CGPoint) circleCenter radius:(CGFloat)radius firstColor:(CGColorRef)firstColor secondeColor:(CGColorRef)secondeColor lineWidth:(CGFloat)lineWidth startDegree:(float)startDegree currentDegree:(float)endDegree { CGContextRef context = UIGraphicsGetCurrentContext(); CGContextSetLineWidth(context, lineWidth); CGContextMoveToPoint(context, circleCenter.x, circleCenter.y); CGContextAddArc(context, circleCenter.x , circleCenter.y, radius, [self radians:startDegree], [self radians:endDegree], 0); CGContextSetFillColorWithColor(context, firstColor); CGContextFillPath(context); CGContextMoveToPoint(context, circleCenter.x, circleCenter.y); CGContextAddArc(context, circleCenter.x, circleCenter.y, radius, [self radians:endDegree], [self radians:startDegree], 0); CGContextSetFillColorWithColor(context, secondeColor); CGContextFillPath(context); } - (void)drawCircleWithCircleCenter2:(CGPoint) circleCenter radius:(CGFloat)radius firstColor:(CGColorRef)firstColor secondeColor:(CGColorRef)secondeColor lineWidth:(CGFloat)lineWidth startDegree:(float)startDegree currentDegree:(float)endDegree { CGContextRef context = UIGraphicsGetCurrentContext(); CGContextSetLineWidth(context, lineWidth); CGContextMoveToPoint(context, circleCenter.x, circleCenter.y); CGContextAddArc(context, circleCenter.x , circleCenter.y, radius, [self radians:startDegree], [self radians:endDegree], 0); CGContextSetFillColorWithColor(context, firstColor); CGContextFillPath(context); CGContextMoveToPoint(context, circleCenter.x, circleCenter.y); CGContextAddArc(context, circleCenter.x, circleCenter.y, radius, [self radians:endDegree], [self radians:startDegree], 0); CGContextSetStrokeColorWithColor(context, secondeColor); CGContextStrokePath(context); } -(float) radians:(double) degrees { return degrees * M_PI / 180; } @end 

observação: você pode usar um dos dois methods: “drawCircleWithCircleCenter” ou “drawCircleWithCircleCenter2”

este código se você quiser dividir a célula em apenas 2 partes

Se você quiser dividir a célula em mais de 2 partes, você pode verificar isso: ” Desenho de um círculo, preenchido diferentes partes com colors diferentes ” e verifique a resposta começar com esta frase “temos 6 class”

Bem, como ninguém usou o NSBezierPath até agora, imaginei que poderia fornecer a solução que usei recentemente para o mesmo problema:

 -(void)drawRect:(NSRect)dirtyRect { double start = -10.0; //degrees double end = 190.0; //degrees NSPoint center = NSMakePoint(350, 200); double radius = 50; NSBezierPath *sector = [NSBezierPath bezierPath]; [sector moveToPoint:center]; [sector appendBezierPathWithArcWithCenter:center radius:radius startAngle:start endAngle:end]; [sector lineToPoint:center]; [sector fill]; } 

Abaixo está um método completo que estou usando que faz isso com o Core Graphics, adaptando e expandindo o comentário do mharper acima.

Este código é para o OSX Cocoa, mas pode ser facilmente alterado para o iOS, modificando como você obtém o contexto.

 - (void)drawPieShapedCircleWithRadius:(CGFloat)radius strokeColor:(CGColorRef)strokeColor fillColor:(CGColorRef)fillColor lineWidth:(CGFloat)lineWidth currentDegrees:(float)currentDegrees startDegrees:(float)startDegrees { // get the context CGContextRef context = [[NSGraphicsContext currentContext] graphicsPort]; // Set the color of the circle stroke and fill CGContextSetStrokeColorWithColor(context, strokeColor); CGContextSetFillColorWithColor(context, fillColor); // Set the line width of the circle CGContextSetLineWidth(context, 1); // Calculate the middle of the circle CGPoint circleCenter = CGPointMake(self.frame.size.width / 2, self.frame.size.height / 2); // Move the bezier to the center of the circle CGContextMoveToPoint(context, circleCenter.x, circleCenter.y); // move to the center point // Draw the arc from the start point (hardcoded as the bottom of the circle) to the center CGContextAddLineToPoint(context, circleCenter.x, circleCenter.y + radius); // Draw the arc around the circle from the start degrees point to the current degrees point CGContextAddArc(context, circleCenter.x , circleCenter.y, radius, [self radians:startDegrees], [self radians:startDegrees + currentDegrees], 0); // Draw the line back into the center of the circle CGContextAddLineToPoint(context, circleCenter.x, circleCenter.y); // Fill the circle CGContextFillPath(context); // Draw the line around the circle CGContextStrokePath(context); } 

Tente este código em um UIView, Exemplo “MyChartClass” …

 - (void)drawRect:(CGRect)rect { int c=(int)[itemArray count]; CGFloat angleArray[c]; CGFloat offset; int sum=0; CGContextRef context = UIGraphicsGetCurrentContext(); CGContextSetAllowsAntialiasing(context, false); CGContextSetShouldAntialias(context, false); for(int i=0;i<[itemArray count];i++) { sum+=[[itemArray objectAtIndex:i] intValue]; } for(int i=0;i<[itemArray count];i++) { angleArray[i]=(float)(([[itemArray objectAtIndex:i] intValue])/(float)sum)*(2*3.14); CGContextMoveToPoint(context, radius, radius); if(i==0) CGContextAddArc(context, radius, radius, radius, 0,angleArray[i], 0); else CGContextAddArc(context, radius, radius, radius,offset,offset+angleArray[i], 0); offset+=angleArray[i]; CGContextSetFillColorWithColor(context, ((UIColor *)[myColorArray objectAtIndex:i]).CGColor); CGContextClosePath(context); CGContextFillPath(context); } } 

Implementação no seu UIViewController

 MyChartClass *myChartClass=[[MyChartClass alloc]initWithFrame:CGRectMake(0, 0, 200, 200)]; myChartClass.backgroundColor = [UIColor clearColor]; myChartClass.itemArray=[[NSArray alloc]initWithObjects:@"75",@"25", nil]; myChartClass.myColorArray=[[NSArray alloc]initWithObjects:[UIColor blackColor],[UIColor whiteColor], nil]; myChartClass.radius=100; [self.view addSubview:myChartClass]; 

Saudações.