Cómo dibujar un rectángulo redondeado en Core Graphics / Quartz 2D?

Necesito dibujar un contorno para un rectángulo redondeado. Sé que puedo hacer líneas y arcos, pero tal vez también hay una función para las rectas redondeadas.

En lugar de hacer su propio camino de líneas y arcos, puede usar

[UIBezierPath bezierPathWithRoundedRect:cornerRadius:] 

o

 [UIBezierPath bezierPathWithRoundedRect:byRoundingCorners:cornerRadii:] 

(el segundo te permite especificar qué esquinas se redondean)

Disponible en iOS 3.2 o posterior.

No hay una forma preempaquetada para esto, debes combinar arcos para hacer esto, Apple Quartzdemo Project muestra el código para hacer esto, aquí hay una demo de Quartz de referencia y aquí está el código que proporcionan

  // 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); 
  UIBezierPath *bezierPath = [UIBezierPath bezierPathWithRoundedRect:bubbleBounds cornerRadius:15.0]; CGContextSetStrokeColorWithColor(context, [UIColor grayColor].CGColor); [bezierPath stroke]; 

Aquí hay una función que escribí que redondea la entrada utilizando un radio de esquina.

 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; } 

Cómo usar la función, suponiendo que subclase UIView y anule 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); } 

Ejemplo de salida:

enter image description here

Si desea tener esquinas redondeadas en cualquier UIView (o subclase), la manera más fácil es establecer la propiedad cornerRadius en la capa de la vista. Ver Vista previa de imagen redondeada en iphone

CGPathCreateWithRoundedRect() hará lo que quieras.

 CGPathRef CGPathCreateWithRoundedRect( CGRect rect, CGFloat cornerWidth, CGFloat cornerHeight, const CGAffineTransform *transform ); 

Disponible a partir de iOS 7.0

Rápido:

  let rect: CGRect = ... let path = UIBezierPath(roundedRect: rect, cornerRadius: 5.0) CGContextAddPath(context, path.CGPath) CGContextSetStrokeColorWithColor(context, UIColor.clearColor().CGColor) CGContextDrawPath(context, CGPathDrawingMode.FillStroke) 

Tal vez … ¿tres? años tarde, pero en estos días estoy usando esto sin problemas.

 @import CoreGraphics; @interface YourViewController () @property (weak, nonatomic) IBOutlet UIButton *theButton; @end - (void)viewDidLoad { [super viewDidLoad]; self.theButton.layer.cornerRadius = 5.0f; self.theButton.layer.masksToBounds = YES; // Another useful ones // Scaling the view (width, height) self.theButton.transform = CGAfflineTransformMakeScale(1.50f, 1.50f); // Setting an alpha value (transparency) - nice with Activity Indicator subviews self.theButton.alpha = 0.8f; }