Dibuja parte de un círculo

Para una aplicación de iPhone, quiero dibujar un círculo, que es solo para un porcentaje x lleno.

Algo como esto:

texto alternativo

No tengo problemas para calcular el radio, los grados o los radianes, eso no es problema. También dibujar el círculo ya está hecho. Pero, ¿cómo obtengo el SDK de iPhone para dibujar la parte que está llena?

Puedo dibujar un rectángulo de ese tamaño, pero no forma parte de un círculo.

Solo quiero dibujar eso en un contexto normal.

Espero que alguien me pueda dar algunos consejos aquí.

Use las funciones de arco de CGContext :

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

Consulte la documentación de CGContextAddArc() .

Mucha gente te ha mostrado cómo se puede hacer esto en Core Graphics, pero también se puede hacer con Core Animation, que ofrece la gran ventaja de poder animar fácilmente el porcentaje de la forma del pastel.

El siguiente código creará el anillo y las capas parcialmente llenas (aunque dijiste que ya puedes dibujar el anillo), ya que es bueno tener el anillo y la forma del pastel para dibujar usando el mismo método.

Si anima las propiedades strokeStart o strokeEnd de la capa pieShape, tendrá el porcentaje animado. Al igual que con todos los códigos Core Animation, necesitará agregar QuartzCore.framework a su proyecto e incluir en su 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]; 

Prueba esto:

 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 

Implementé una vista de progreso circular que se parece a lo que está haciendo. Es de código abierto. Con suerte, el código fuente ayudará.

Fuente SSPieProgressView.h

Fuente 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 

nota: puede usar uno de los 2 métodos: “drawCircleWithCircleCenter” o “drawCircleWithCircleCenter2”

este código si desea dividir la celda en 2 partes solamente

Si desea dividir la celda en más de 2 partes, puede verificar esto: ” Dibujando un círculo, rellenar diferentes partes con diferentes colores ” y comprobar que la respuesta comience con esta Frase “tenemos 6 clases”

Bueno, como nadie usó NSBezierPath hasta ahora, pensé que podría proporcionar la solución que utilicé recientemente para el mismo 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]; } 

A continuación se muestra un método completo que estoy usando que hace esto con Core Graphics, adaptándose y expandiéndose en el comentario de mharper anterior.

Este código es para OSX Cocoa, pero podría cambiarse fácilmente a iOS modificando cómo se obtiene el 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); } 

Pruebe este código en una UIView, Ejemplo “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); } } 

Implementación en su 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]; 

Saludos.