66 votes

Comment dessiner un rectangle arrondi dans Core Graphics / Quartz 2D ?

Je dois dessiner le contour d'un rectangle arrondi. Je sais que je peux tracer des lignes et des arcs, mais peut-être existe-t-il aussi une fonction pour les rectangles arrondis ?

0 votes

131voto

Timo Bruck Points 4713

Au lieu de créer votre propre chemin à partir de lignes et d'arcs, vous pouvez utiliser

[UIBezierPath bezierPathWithRoundedRect:cornerRadius:]

o

[UIBezierPath bezierPathWithRoundedRect:byRoundingCorners:cornerRadii:]

(le second vous permet de spécifier quels coins sont arrondis)

Disponible dans iOS 3.2 ou plus.

7 votes

N'oubliez pas d'insérer correctement le rectangle lors de la frappe, même si la largeur de votre ligne n'est que d'un pixel : CGRectInset(rect, lineWidth, lineWidth)

21 votes

Pour être complet, il est également utile de montrer ce que vous faites avec ça : objc [[UIColor lightGrayColor] setFill]; // set rounded rect's bg color UIBezierPath *roundedRect = [UIBezierPath bezierPathWithRoundedRect: _yourDrawingFrame cornerRadius: 4]; [roundedRect fillWithBlendMode: kCGBlendModeNormal alpha:1.0f];

9 votes

En fait, je pense que le rectangle ne devrait être inséré que de la moitié de la largeur de la ligne. CGRectInset(rect, lineWidth/2.0, lineWidth/2.0) . En effet, "la ligne tracée est centrée sur le chemin et ses côtés sont parallèles au segment de chemin" (cf. -[UIBezierPath strokeWithBlendMode:alpha:] )

62voto

Daniel Points 16707

Il n'y a pas de méthode préemballée pour cela, vous devez combiner les arcs pour le faire, le projet quartzdemo montre le code pour le faire, voici une référence. Démo Quartz et voici le code qu'ils fournissent

  // As a bonus, we'll combine arcs to create a round rectangle! 

// Drawing with a white stroke color 
 CGContextRef context=UIGraphicsGetCurrentContext()
CGContextSetRGBStrokeColor(context, 1.0, 1.0, 1.0, 1.0); 

// If you were making this as a routine, you would probably accept a rectangle 
// that defines its bounds, and a radius reflecting the "rounded-ness" of the rectangle. 
CGRect rrect = CGRectMake(210.0, 90.0, 60.0, 60.0); 
CGFloat radius = 10.0; 
// NOTE: At this point you may want to verify that your radius is no more than half 
// the width and height of your rectangle, as this technique degenerates for those cases. 

// In order to draw a rounded rectangle, we will take advantage of the fact that 
// CGContextAddArcToPoint will draw straight lines past the start and end of the arc 
// in order to create the path from the current position and the destination position. 

// In order to create the 4 arcs correctly, we need to know the min, mid and max positions 
// on the x and y lengths of the given rectangle. 
CGFloat minx = CGRectGetMinX(rrect), midx = CGRectGetMidX(rrect), maxx = CGRectGetMaxX(rrect); 
CGFloat miny = CGRectGetMinY(rrect), midy = CGRectGetMidY(rrect), maxy = CGRectGetMaxY(rrect); 

// Next, we will go around the rectangle in the order given by the figure below. 
//       minx    midx    maxx 
// miny    2       3       4 
// midy   1 9              5 
// maxy    8       7       6 
// Which gives us a coincident start and end point, which is incidental to this technique, but still doesn't 
// form a closed path, so we still need to close the path to connect the ends correctly. 
// Thus we start by moving to point 1, then adding arcs through each pair of points that follows. 
// You could use a similar tecgnique to create any shape with rounded corners. 

// Start at 1 
CGContextMoveToPoint(context, minx, midy); 
// Add an arc through 2 to 3 
CGContextAddArcToPoint(context, minx, miny, midx, miny, radius); 
// Add an arc through 4 to 5 
CGContextAddArcToPoint(context, maxx, miny, maxx, midy, radius); 
// Add an arc through 6 to 7 
CGContextAddArcToPoint(context, maxx, maxy, midx, maxy, radius); 
// Add an arc through 8 to 9 
CGContextAddArcToPoint(context, minx, maxy, minx, midy, radius); 
// Close the path 
CGContextClosePath(context); 
// Fill & stroke the path 
CGContextDrawPath(context, kCGPathFillStroke);

3 votes

Si quelqu'un se demande comment CGContextAddArcToPoint() travaux, ce est une assez bonne explication.

48voto

proca 2.0 Points 1476
 UIBezierPath *bezierPath = [UIBezierPath bezierPathWithRoundedRect:bubbleBounds cornerRadius:15.0];
 CGContextSetStrokeColorWithColor(context, [UIColor grayColor].CGColor);
 [bezierPath stroke];

23voto

Erik Villegas Points 315

Voici une fonction que j'ai écrite qui arrondit le rectangle d'entrée en utilisant un rayon d'angle.

CGMutablePathRef createRoundedCornerPath(CGRect rect, CGFloat cornerRadius) {

    // create a mutable path
    CGMutablePathRef path = CGPathCreateMutable();

    // get the 4 corners of the rect
    CGPoint topLeft = CGPointMake(rect.origin.x, rect.origin.y);
    CGPoint topRight = CGPointMake(rect.origin.x + rect.size.width, rect.origin.y);
    CGPoint bottomRight = CGPointMake(rect.origin.x + rect.size.width, rect.origin.y + rect.size.height);
    CGPoint bottomLeft = CGPointMake(rect.origin.x, rect.origin.y + rect.size.height);

    // move to top left
    CGPathMoveToPoint(path, NULL, topLeft.x + cornerRadius, topLeft.y);

    // add top line
    CGPathAddLineToPoint(path, NULL, topRight.x - cornerRadius, topRight.y);

    // add top right curve
    CGPathAddQuadCurveToPoint(path, NULL, topRight.x, topRight.y, topRight.x, topRight.y + cornerRadius);

    // add right line
    CGPathAddLineToPoint(path, NULL, bottomRight.x, bottomRight.y - cornerRadius);

    // add bottom right curve
    CGPathAddQuadCurveToPoint(path, NULL, bottomRight.x, bottomRight.y, bottomRight.x - cornerRadius, bottomRight.y);

    // add bottom line
    CGPathAddLineToPoint(path, NULL, bottomLeft.x + cornerRadius, bottomLeft.y);

    // add bottom left curve
    CGPathAddQuadCurveToPoint(path, NULL, bottomLeft.x, bottomLeft.y, bottomLeft.x, bottomLeft.y - cornerRadius);

    // add left line
    CGPathAddLineToPoint(path, NULL, topLeft.x, topLeft.y + cornerRadius);

    // add top left curve
    CGPathAddQuadCurveToPoint(path, NULL, topLeft.x, topLeft.y, topLeft.x + cornerRadius, topLeft.y);

    // return the path
    return path;
}

Comment utiliser la fonction, en supposant que vous sous-classez UIView et que vous surchargez drawRect :

- (void)drawRect:(CGRect)rect {

    // constants
    const CGFloat outlineStrokeWidth = 20.0f;
    const CGFloat outlineCornerRadius = 15.0f;

    const CGColorRef whiteColor = [[UIColor whiteColor] CGColor];
    const CGColorRef redColor = [[UIColor redColor] CGColor];

    // get the context
    CGContextRef context = UIGraphicsGetCurrentContext();

    // set the background color to white
    CGContextSetFillColorWithColor(context, whiteColor);
    CGContextFillRect(context, rect);

    // inset the rect because half of the stroke applied to this path will be on the outside
    CGRect insetRect = CGRectInset(rect, outlineStrokeWidth/2.0f, outlineStrokeWidth/2.0f);

    // get our rounded rect as a path
    CGMutablePathRef path = createRoundedCornerPath(insetRect, outlineCornerRadius);

    // add the path to the context
    CGContextAddPath(context, path);

    // set the stroke params
    CGContextSetStrokeColorWithColor(context, redColor);
    CGContextSetLineWidth(context, outlineStrokeWidth);

    // draw the path
    CGContextDrawPath(context, kCGPathStroke);

    // release the path
    CGPathRelease(path);
}

Exemple de sortie :

enter image description here

1 votes

Allez-y et utilisez les fonctions intégrées. Je l'ai fait à des fins d'apprentissage uniquement.

0 votes

Cela ne fonctionne pas : CGMutablePathRef path = createRoundedCornerPath(insetRect, outlineCornerRadius) ;

0 votes

Assurez-vous que vous avez copié l'implémentation de la fonction createRoundedCornerPath() incluse dans ma réponse. Elle doit également être placée au-dessus de la méthode drawRect : puisqu'il s'agit d'une fonction C.

11voto

progrmr Points 32412

Si vous voulez avoir des coins arrondis sur n'importe quelle UIView (ou sous-classe), le moyen le plus simple est de définir la propriété cornerRadius sur le calque de la vue. Voir Prévisualisation d'une image arrondie dans l'iphone

4 votes

C'est de loin le plus facile. view.layer.cornerRadius = 10.0f. Assurez-vous que vous importez le framework Quartz.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X