如何在 iPhone 上绘制一个带有剪角而非圆角的矩形?

发布于 2024-09-16 20:31:15 字数 169 浏览 3 评论 0原文

我看到了很多如何使用 iPhone SDK 绘制圆角矩形的示例。我真正需要的是一个修剪过的角矩形,如下所示:

alt text

谢谢, 乔什

I saw many examples of how to draw a rounded rectangle using iPhone SDK. What I really need is a trimmed corner rectangle, something that will look as follows:

alt text

Thanks,
Josh

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

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

发布评论

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

评论(2

豆芽 2024-09-23 20:31:16

(这是为了采纳 Jonathan Grynspan 的建议而进行编辑的,只需使用辅助函数来创建路径。现在它还允许修剪角的高度与其宽度不同。)

这是一个辅助 C 函数来创建这样的路径:

// Note: caller is responsible for releasing the returned path
CGPathRef createAngledCornerRectPath(CGRect rect,
                                     CGSize cornerSize,
                                     CGFloat strokeWidth)
{
    CGMutablePathRef p = CGPathCreateMutable();

    // Make points for the corners
    CGFloat inset = strokeWidth/2; // because the stroke is centered on the path.
    CGPoint tlc = CGPointMake(CGRectGetMinX(rect) + inset,
                              CGRectGetMinY(rect) + inset);
    CGPoint trc = CGPointMake(CGRectGetMaxX(rect) - inset,
                              CGRectGetMinY(rect) + inset);
    CGPoint blc = CGPointMake(CGRectGetMinX(rect) + inset,
                              CGRectGetMaxY(rect) - inset);
    CGPoint brc = CGPointMake(CGRectGetMaxX(rect) - inset,
                              CGRectGetMaxY(rect) - inset);

    // Start in top left and move around counter-clockwise.
    CGPathMoveToPoint(p, NULL, tlc.x, tlc.y+cornerSize.height);
    CGPathAddLineToPoint(p, NULL, blc.x, blc.y-cornerSize.height);
    CGPathAddLineToPoint(p, NULL, blc.x+cornerSize.width, blc.y);
    CGPathAddLineToPoint(p, NULL, brc.x-cornerSize.width, brc.y);
    CGPathAddLineToPoint(p, NULL, brc.x, brc.y-cornerSize.height);
    CGPathAddLineToPoint(p, NULL, trc.x, trc.y+cornerSize.height);
    CGPathAddLineToPoint(p, NULL, trc.x-cornerSize.width, trc.y);
    CGPathAddLineToPoint(p, NULL, tlc.x+cornerSize.width, trc.y);
    CGPathCloseSubpath(p);

    return p;
}

以下是如何在自定义视图的 -drawRect: 方法中使用它:

- (void)drawRect:(CGRect)rect
{
    // Define a few parameters
    CGSize cornerSize = CGSizeMake(30.f, 30.f);
    CGFloat strokeWidth = 3.f;
    CGColorRef strokeColor = [UIColor redColor].CGColor;

    CGContextRef c = UIGraphicsGetCurrentContext();
    CGContextSetStrokeColorWithColor(c, strokeColor);
    CGContextSetLineWidth(c, strokeWidth);

    // Create the path, add it to the context, and stroke it.
    CGPathRef path = createAngledCornerRectPath(rect,
                                                cornerSize,
                                                strokeWidth);
    CGContextAddPath(c, path);
    CGContextStrokePath(c);

    // we are responsible for releasing the path
    CGPathRelease(path);
}

(This is edited to take Jonathan Grynspan's suggestion and just use the helper function to create a path. It also now allows for the trimmed corner's height to be different from its width.)

Here is a helper C-function to create a such a path:

// Note: caller is responsible for releasing the returned path
CGPathRef createAngledCornerRectPath(CGRect rect,
                                     CGSize cornerSize,
                                     CGFloat strokeWidth)
{
    CGMutablePathRef p = CGPathCreateMutable();

    // Make points for the corners
    CGFloat inset = strokeWidth/2; // because the stroke is centered on the path.
    CGPoint tlc = CGPointMake(CGRectGetMinX(rect) + inset,
                              CGRectGetMinY(rect) + inset);
    CGPoint trc = CGPointMake(CGRectGetMaxX(rect) - inset,
                              CGRectGetMinY(rect) + inset);
    CGPoint blc = CGPointMake(CGRectGetMinX(rect) + inset,
                              CGRectGetMaxY(rect) - inset);
    CGPoint brc = CGPointMake(CGRectGetMaxX(rect) - inset,
                              CGRectGetMaxY(rect) - inset);

    // Start in top left and move around counter-clockwise.
    CGPathMoveToPoint(p, NULL, tlc.x, tlc.y+cornerSize.height);
    CGPathAddLineToPoint(p, NULL, blc.x, blc.y-cornerSize.height);
    CGPathAddLineToPoint(p, NULL, blc.x+cornerSize.width, blc.y);
    CGPathAddLineToPoint(p, NULL, brc.x-cornerSize.width, brc.y);
    CGPathAddLineToPoint(p, NULL, brc.x, brc.y-cornerSize.height);
    CGPathAddLineToPoint(p, NULL, trc.x, trc.y+cornerSize.height);
    CGPathAddLineToPoint(p, NULL, trc.x-cornerSize.width, trc.y);
    CGPathAddLineToPoint(p, NULL, tlc.x+cornerSize.width, trc.y);
    CGPathCloseSubpath(p);

    return p;
}

And here is how you would use this in your custom view's -drawRect: method:

- (void)drawRect:(CGRect)rect
{
    // Define a few parameters
    CGSize cornerSize = CGSizeMake(30.f, 30.f);
    CGFloat strokeWidth = 3.f;
    CGColorRef strokeColor = [UIColor redColor].CGColor;

    CGContextRef c = UIGraphicsGetCurrentContext();
    CGContextSetStrokeColorWithColor(c, strokeColor);
    CGContextSetLineWidth(c, strokeWidth);

    // Create the path, add it to the context, and stroke it.
    CGPathRef path = createAngledCornerRectPath(rect,
                                                cornerSize,
                                                strokeWidth);
    CGContextAddPath(c, path);
    CGContextStrokePath(c);

    // we are responsible for releasing the path
    CGPathRelease(path);
}
坦然微笑 2024-09-23 20:31:16

我只使用 8 条线段(起始路径、向路径添加线、结束路径、描边路径)。
您只需要从每个 x 或 y 角坐标中添加或减去一些常数即可获得所有 8 个点。您可以编写一个与 CGStrokeRect 具有相同 api 的简单函数来封装上述所有内容。

I would just use 8 line segments (start path, add line to path, end path, stroke path).
You would just need to add or subtract some constant from each x or y corner coordinate to get all 8 points. You could write a simple function with the same api as CGStrokeRect to encapsulate all the above.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文