How to draw a rounded rectangle in Core Graphics / Quartz 2D?

后端 未结 9 1060
盖世英雄少女心
盖世英雄少女心 2020-11-29 18:15

I need to draw an outline for a rounded rectangle. I know I can make lines and arcs, but maybe there is also a function for rounded rects?

相关标签:
9条回答
  • 2020-11-29 18:27

    Instead of making your own path out of lines and arcs, you can use

    [UIBezierPath bezierPathWithRoundedRect:cornerRadius:]
    

    or

    [UIBezierPath bezierPathWithRoundedRect:byRoundingCorners:cornerRadii:]
    

    (the second one lets you specify which corners are rounded)

    Available in iOS 3.2 or later.

    0 讨论(0)
  • 2020-11-29 18:29

    Here is a function I wrote that rounds the input rect using a corner radius.

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

    How to use the function, assuming you subclass UIView and override 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);
    }
    

    Example output:

    enter image description here

    0 讨论(0)
  • 2020-11-29 18:30

    If you want To have rounded corners on any UIView (or subclass) the easy way is to set the cornerRadius property on the view's layer. See Preview rounded image in iphone

    0 讨论(0)
  • 2020-11-29 18:33
     UIBezierPath *bezierPath = [UIBezierPath bezierPathWithRoundedRect:bubbleBounds cornerRadius:15.0];
     CGContextSetStrokeColorWithColor(context, [UIColor grayColor].CGColor);
     [bezierPath stroke];
    
    0 讨论(0)
  • 2020-11-29 18:36

    Maybe... three? years late, but these days I'm using this without issues.

    @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;
    }
    
    0 讨论(0)
  • 2020-11-29 18:45

    There is no prepackaged way to this, you must combine arcs in order to do this, apples quartzdemo project shows the code to do this, here is a reference Quartz Demo and here is the code they provide

      // 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); 
    
    0 讨论(0)
提交回复
热议问题