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

Posted

技术标签:

【中文标题】如何在 iPhone 上绘制一个带有剪裁而不是圆角的矩形?【英文标题】:How do I draw a rectangle with clipped, not rounded, corners on the iPhone? 【发布时间】:2010-08-28 17:08:46 【问题描述】:

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

谢谢, 乔什

【问题讨论】:

用什么库?您可以使用 OpenGL ES 或 CGGeometry(甚至是 Cocos2d,但您可能不会)。 这并不重要。只求最简单的解决方案 【参考方案1】:

(根据 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);

【讨论】:

这很好,但我会将它进一步概括为一个返回 CGPath 对象的函数——这样,它可以用于填充形状、描边、剪辑等。【参考方案2】:

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

【讨论】:

以上是关于如何在 iPhone 上绘制一个带有剪裁而不是圆角的矩形?的主要内容,如果未能解决你的问题,请参考以下文章

UIView 上的自定义圆角

UIView 上的自定义圆角

带有圆角而不是 100% 屏幕宽度的自定义片段对话框

如何仅从单面绘制带有色调颜色和圆角的 UIButton

左侧单点触控 iphone 上带有圆角的 UIImage

如何使多边形在ggplot中被剪裁而不是消失