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

发布于 2024-09-01 10:00:49 字数 47 浏览 6 评论 0原文

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

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

不…忘初心 2024-09-08 10:00:49

,而不是用直线和圆弧创建自己的路径。

[UIBezierPath bezierPathWithRoundedRect:cornerRadius:]

您可以使用or

[UIBezierPath bezierPathWithRoundedRect:byRoundingCorners:cornerRadii:]

(第二个让您指定哪些角是圆角的)

iOS 3.2 或更高版本中提供。

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.

乱世争霸 2024-09-08 10:00:49

没有预先打包的方法,您必须组合弧才能做到这一点,苹果的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); 

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); 
尾戒 2024-09-08 10:00:49
 UIBezierPath *bezierPath = [UIBezierPath bezierPathWithRoundedRect:bubbleBounds cornerRadius:15.0];
 CGContextSetStrokeColorWithColor(context, [UIColor grayColor].CGColor);
 [bezierPath stroke];
 UIBezierPath *bezierPath = [UIBezierPath bezierPathWithRoundedRect:bubbleBounds cornerRadius:15.0];
 CGContextSetStrokeColorWithColor(context, [UIColor grayColor].CGColor);
 [bezierPath stroke];
半仙 2024-09-08 10:00:49

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

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

如何使用该函数,假设您继承了 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);
}

示例输出:

在此处输入图像描述

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

人心善变 2024-09-08 10:00:49

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

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

怎樣才叫好 2024-09-08 10:00:49

< code>CGPathCreateWithRoundedRect() 会做你想要的。

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

从 iOS 7.0 开始可用

CGPathCreateWithRoundedRect() will do what you want.

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

Available starting in iOS 7.0

寄居者 2024-09-08 10:00:49

斯威夫特:

    let rect: CGRect = ...
    
    let path = UIBezierPath(roundedRect: rect, cornerRadius: 5.0)
    context.addPath(path.cgPath)
    context.setStrokeColor(UIColor.clear.cgColor)
    context.drawPath(using: .fillStroke)

Swift:

    let rect: CGRect = ...
    
    let path = UIBezierPath(roundedRect: rect, cornerRadius: 5.0)
    context.addPath(path.cgPath)
    context.setStrokeColor(UIColor.clear.cgColor)
    context.drawPath(using: .fillStroke)
涫野音 2024-09-08 10:00:49

也许……三个?晚了几年,但这些天我使用它没有任何问题。

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

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;
}
神魇的王 2024-09-08 10:00:49

斯威夫特 4.2

    let lineWidth: CGFloat = 5.0
    let path = UIBezierPath(roundedRect: rect.insetBy(dx: lineWidth/2.0, dy: lineWidth/2.0), cornerRadius: 10。0)
    path.lineWidth = lineWidth
    UIColor.green.setStroke()
    path.stroke()

Swift 4.2

    let lineWidth: CGFloat = 5.0
    let path = UIBezierPath(roundedRect: rect.insetBy(dx: lineWidth/2.0, dy: lineWidth/2.0), cornerRadius: 10。0)
    path.lineWidth = lineWidth
    UIColor.green.setStroke()
    path.stroke()
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文