Tirer partie d'un cercle

Pour une application iPhone je veux dessiner un cercle, c'est uniquement pour un x pourcentage rempli.

Quelque Chose comme ceci:

le texte d'alt

Je n'ai aucun problème à calculer le Rayon, les degrés ou les radians, ce n'est pas un problème. Aussi dessiner le cercle est déjà fait. Mais comment puis-je obtenir le SDK iPhone pour dessiner la partie qui est remplie.

Je peux dessiner un rectangle de cette taille, mais pas une partie d'un cercle.

Je veux juste dessiner cela sur une normale cadre.

J'espère que quelqu'un peut me donner des conseils ici.

25
demandé sur Wim Haanstra 2010-09-16 22:39:32

8 réponses

Utiliser les fonctions d'arc de CGContext:

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

Voir la documentation pour CGContextAddArc().

20
répondu David M. 2014-03-16 23:16:56

Beaucoup de gens vous ont montré comment cela peut être fait dans les graphiques de base, mais cela peut aussi être fait avec L'Animation de base qui donne le gros ajout de pouvoir facilement animer le pourcentage de la forme de tarte.

Le code suivant va créer à la fois l'anneau et les couches partiellement remplies (même si vous avez dit que vous pouvez déjà dessiner l'anneau) car il est agréable d'avoir à la fois l'anneau et la forme de tarte à dessiner en utilisant la même méthode.

Si vous animez le strokeStart oustrokeend propriétés du calque pieShape vous aurez le pourcentage d'animation. Comme avec tout le code D'Animation de base, vous devrez ajouter QuartzCore.cadre de votre projet et incluez <QuartzCore/QuartzCore.h> dans votre code.

// 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];
45
répondu David Rönnqvist 2014-03-16 22:58:09

Essayez ceci:

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
8
répondu mharper 2010-09-16 21:14:08

J'ai implémenté une vue de progression pie qui ressemble à ce que vous faites. Il est open source. Espérons que le code source aidera.

SSPieProgressView.h source

SSPieProgressView.m source

6
répondu Sam Soffes 2011-02-19 01:26:55

CircleViewController.h

#import <UIKit/UIKit.h>

@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 <UIKit/UIKit.h>

@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

Remarque: vous pouvez utiliser l'une des 2 méthodes: "drawCircleWithCircleCenter" ou "drawCircleWithCircleCenter2"

Ce code si vous souhaitez fractionner la cellule sur 2 parties seulement

Si vous souhaitez fractionner la cellule sur plus de 2 parties, vous pouvez vérifier ceci : "Dessiner un cercle ,rempli différentes parties avec une couleur différente "et vérifiez la réponse commencez par cette Phrase" nous avons 6 Classe "

2
répondu Mohamad Chami 2017-05-23 12:09:23

Eh bien, puisque personne n'a utilisé NSBezierPath jusqu'à présent, j'ai pensé que je pourrais fournir la solution que j'ai récemment utilisée pour le même problème:

-(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];
}
1
répondu Atomix 2014-08-20 21:13:09

Ci-dessous est une méthode complète que j'utilise qui le fait avec des graphiques de base, en adaptant et en développant le commentaire de mharper ci-dessus.

Ce code est pour OSX Cocoa, mais pourrait facilement être changé en iOS, en modifiant la façon dont vous obtenez le contexte.

- (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);
}
0
répondu Scott Allen 2013-02-28 06:50:22

Essayez ce code dans un UIView, exemple "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);

    }   
}

Implémentation dans votre 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];

Cordialement.

0
répondu Jaime 2014-07-22 15:00:02