如何在Core Graphics/Quartz 2D中绘制圆角矩形?

don*_*ile 63 iphone quartz-graphics

我需要为圆角矩形绘制轮廓.我知道我可以制作线条和弧线,但也许还有一个圆形的功能?

Tim*_*uck 127

您可以使用,而不是使用自己的线路和弧线

[UIBezierPath bezierPathWithRoundedRect:cornerRadius:]
Run Code Online (Sandbox Code Playgroud)

要么

[UIBezierPath bezierPathWithRoundedRect:byRoundingCorners:cornerRadii:]
Run Code Online (Sandbox Code Playgroud)

(第二个允许您指定哪些角被舍入)

适用于iOS 3.2或更高版本.

  • 只是为了完整性,显示你用它做什么也很有帮助:````objc [[UIColor lightGrayColor] setFill]; //设置圆角矩形的bg颜色UIBezierPath*roundedRect = [UIBezierPath bezierPathWithRoundedRect:_yourDrawingFrame cornerRadius:4]; [roundedRect fillWithBlendMode:kCGBlendModeNormal alpha:1.0f]; ``` (20认同)
  • 实际上在抚摸时我相信rect应该只插入lineWidth的一半,即`CGRectInset(rect,lineWidth/2.0,lineWidth/2.0)`.这是因为"绘制的线以路径为中心,其边与路径段平行"(参见` - [UIBezierPath strokeWithBlendMode:alpha:]`) (9认同)
  • 即使你的线宽只有一个像素,也不要忘记在抚摸时正确插入矩形:`CGRectInset(rect,lineWidth,lineWidth)` (7认同)

Dan*_*iel 59

没有预先打包的方法,你必须结合弧来做到这一点,苹果quartzdemo项目显示了这样做的代码,这里是一个参考Quartz Demo,这里是他们提供的代码

  // 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); 
Run Code Online (Sandbox Code Playgroud)

  • 如果有人想知道`CGContextAddArcToPoint()`如何工作,[this](http://stackoverflow.com/a/18992153/1338292)是一个很好的解释. (3认同)

car*_*ich 43

 UIBezierPath *bezierPath = [UIBezierPath bezierPathWithRoundedRect:bubbleBounds cornerRadius:15.0];
 CGContextSetStrokeColorWithColor(context, [UIColor grayColor].CGColor);
 [bezierPath stroke];
Run Code Online (Sandbox Code Playgroud)


Eri*_*gas 23

这是我写的一个函数,它使用圆角半径对输入矩形进行舍入.

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;
}
Run Code Online (Sandbox Code Playgroud)

如何使用该函数,假设你是UIView的子类并覆盖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);
}
Run Code Online (Sandbox Code Playgroud)

示例输出:

在此输入图像描述


pro*_*rmr 11

如果你想要在任何UIView(或子类)上有圆角,那么简单的方法是在视图的图层上设置cornerRadius属性.请参阅在iPhone中预览圆形图像

  • 这是迄今为止最容易的.view.layer.cornerRadius = 10.0f.确保导入Quartz框架. (4认同)

Cra*_*ler 9

CGPathCreateWithRoundedRect() 会做你想做的.

CGPathRef CGPathCreateWithRoundedRect(
   CGRect rect,
   CGFloat cornerWidth,
   CGFloat cornerHeight,
   const CGAffineTransform *transform
);
Run Code Online (Sandbox Code Playgroud)

从iOS 7.0开始提供

  • 我很确定这不会给你新的iOS7圆角.使用bezierPathWithRoundedRect用于新的iOS7圆角...... (3认同)

Ale*_*kov 8

迅速:

    let rect: CGRect = ...

    let path = UIBezierPath(roundedRect: rect, cornerRadius: 5.0)
    CGContextAddPath(context, path.CGPath)
    CGContextSetStrokeColorWithColor(context, UIColor.clearColor().CGColor)
    CGContextDrawPath(context, CGPathDrawingMode.FillStroke)
Run Code Online (Sandbox Code Playgroud)