用平行线填充UIBezierPath

5

我正在尝试使用UIBezierPath绘制自定义形状:

UIBezierPath *aPath = [UIBezierPath bezierPath];

    [aPath moveToPoint:CGPointMake(100.0, 0.0)];

    // Draw the lines.
    [aPath addLineToPoint:CGPointMake(200.0, 40.0)];
    [aPath addLineToPoint:CGPointMake(160, 140)];
    [aPath addLineToPoint:CGPointMake(40.0, 140)];
    [aPath addLineToPoint:CGPointMake(0.0, 40.0)];
    [aPath closePath];

我想用平行线来填充它,使其呈现条纹效果。我也想改变这些线的颜色。

假设我想让这些线垂直排列,我需要以固定间隔计算出路径上的点,我应该怎么做?

我发现了这个UIColor colorWithPatternImage,但是我不能改变形状内部线条的颜色和密度。

3个回答

6

就像 Nikolai Ruhe 所说,最好的选择是使用您的形状作为剪切路径,然后在形状边界框内绘制一些模式。以下是代码示例:

- (void)drawRect:(CGRect)rect
{
    // create a UIBezierPath for the outline shape
    UIBezierPath *aPath = [UIBezierPath bezierPath];
    [aPath moveToPoint:CGPointMake(100.0, 0.0)];
    [aPath addLineToPoint:CGPointMake(200.0, 40.0)];
    [aPath addLineToPoint:CGPointMake(160, 140)];
    [aPath addLineToPoint:CGPointMake(40.0, 140)];
    [aPath addLineToPoint:CGPointMake(0.0, 40.0)];
    [aPath closePath];
    [aPath setLineWidth:10];

    // get the bounding rectangle for the outline shape
    CGRect bounds = aPath.bounds;

    // create a UIBezierPath for the fill pattern
    UIBezierPath *stripes = [UIBezierPath bezierPath];
    for ( int x = 0; x < bounds.size.width; x += 20 )
    {
        [stripes moveToPoint:CGPointMake( bounds.origin.x + x, bounds.origin.y )];
        [stripes addLineToPoint:CGPointMake( bounds.origin.x + x, bounds.origin.y + bounds.size.height )];
    }
    [stripes setLineWidth:10];

    CGContextRef context = UIGraphicsGetCurrentContext();

    // draw the fill pattern first, using the outline to clip
    CGContextSaveGState( context );         // save the graphics state
    [aPath addClip];                        // use the outline as the clipping path
    [[UIColor blueColor] set];              // blue color for vertical stripes
    [stripes stroke];                       // draw the stripes
    CGContextRestoreGState( context );      // restore the graphics state, removes the clipping path

    // draw the outline of the shape
    [[UIColor greenColor] set];             // green color for the outline
    [aPath stroke];                         // draw the outline
}

使用Swift


override func draw(_ rect: CGRect){

        // create a UIBezierPath for the outline shape
        let aPath = UIBezierPath()
        aPath.move(to: CGPoint(x: 100.0, y: 0.0))
        aPath.addLine(to: CGPoint(x: 200.0, y: 40.0))
        aPath.addLine(to: CGPoint(x: 160, y: 140))
        aPath.addLine(to: CGPoint(x: 40.0, y: 140))
        aPath.addLine(to: CGPoint(x: 0.0, y: 40.0))
        aPath.close()
        aPath.lineWidth = 10

        // get the bounding rectangle for the outline shape
        let bounds = aPath.bounds

        // create a UIBezierPath for the fill pattern
        let stripes = UIBezierPath()
        for x in stride(from: 0, to: bounds.size.width, by: 20){
            stripes.move(to: CGPoint(x: bounds.origin.x + x, y: bounds.origin.y ))
            stripes.addLine(to: CGPoint(x: bounds.origin.x + x, y: bounds.origin.y + bounds.size.height ))
        }
        stripes.lineWidth = 10

        let context = UIGraphicsGetCurrentContext()

        // draw the fill pattern first, using the outline to clip
        context!.saveGState()         // save the graphics state
        aPath.addClip()                        // use the outline as the clipping path
        UIColor.blue.set()                    // blue color for vertical stripes
        stripes.stroke()                       // draw the stripes
        context!.restoreGState()      // restore the graphics state, removes the clipping path

        // draw the outline of the shape
        UIColor.green.set()             // green color for the outline
        aPath.stroke()                         // draw the outline
    }

产生的结果

enter image description here


非常感谢,我会尝试做到,如果出现其他问题,我会告诉你。 - Prettygeek

2
最好的选择是将要绘制的原始形状作为剪切路径(CGContextClip)设置在上下文中。
现在,只需将所有平行线绘制到形状的边界框中。您可以自由地改变线条的颜色或距离。

据我理解,剪辑会限制我绘制在这个UIBezierPath上的空间,即使我画出的线太长也不会超出形状,对吗? - Prettygeek
1
@Preetygeek 没错。剪辑就像一个遮罩,防止颜色触及形状外的任何东西。您可以将所有内容绘制到此遮罩中(形状、文本、图像)。 - Nikolai Ruhe

1

目前我没有相关代码,但你正在正确的道路上使用 [UIColor colorWithPatternImage:...

然而,如果你想让这更加灵活,你可以通过编程生成图像。

你只需要一个非常小的图像,几个像素就足够了,其中包含每种颜色的一条条纹。

如果你的条纹是绿色和红色的,绿色宽度为4个像素而红色为3个像素,那么你只需要一个1像素宽、7像素高的图像。

然后将这个自动生成的图像用作颜色的图案图像。

这可能是我能想到的最简单的方法。

生成图像并不难。有很多关于绘制图像上下文的 SO 问题。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接