iOS:CoreGraphics - 使用CGContextClip和lineCap = .Round剪切弧

时间:2016-06-22 21:18:23

标签: ios swift core-graphics

我有一个弧线,我画了如下:

    func drawBackgroundMask(context: CGContextRef,
                        center: CGPoint,
                        radius: CGFloat,
                        lineWidth: CGFloat,
                        startAngle: CGFloat,
                        endAngle: CGFloat) {
    let adjustedRadius: CGFloat = radius - (lineWidth/2) - 0

    CGContextSetLineWidth(context, lineWidth)
    CGContextSetLineCap(context, .Round)

    CGContextAddArc(context,
                    center.x,
                    center.y,
                    adjustedRadius,
                    startAngle,
                    endAngle,
                    0)

    //CGContextClosePath(context)
    //CGContextClip(context)
    CGContextStrokePath(context)

}

通过上面的注释,我可以创建以下内容:

black arc

但是,如果我尝试通过取消注释上面的两行代码然后将背景绘制为实体来将绘制的形状用作蒙版,我会得到不同的结果:

    func drawBackgroundMask(context: CGContextRef,
                        center: CGPoint,
                        radius: CGFloat,
                        lineWidth: CGFloat,
                        startAngle: CGFloat,
                        endAngle: CGFloat) {
    let adjustedRadius: CGFloat = radius - (lineWidth/2) - 0

    CGContextSetLineWidth(context, lineWidth)
    CGContextSetLineCap(context, .Round)

    CGContextAddArc(context,
                    center.x,
                    center.y,
                    adjustedRadius,
                    startAngle,
                    endAngle,
                    0)

    CGContextClosePath(context)
    CGContextClip(context)
    CGContextStrokePath(context)

    CGContextSetRGBFillColor(context, 100.0/255.0, 100.0/255.0, 100.0/255.0, 1.0);
    CGContextFillRect(context, rect);
}

as mask

有人可以向我解释为什么使用绘制的弧作为剪贴蒙版会导致它的处理方式与绘制的不同吗?此外,任何人都可以告诉我正确的方法来创建一个圆形的圆弧形状的面具?这个问题是我正在研究的一个更大控件的一部分,我必须用弧形显示的形状剪切另一个弧。

1 个答案:

答案 0 :(得分:2)

在第二个示例中,剪辑仅考虑弧的路径。各种行程参数(如线宽,上限等)仅在实际描边路径时使用,而您没有这样做。

首先在CGContext中设置一个路径,然后剪辑它。之后消耗上下文中的路径。正如the documentation所说:

  

确定新的剪切路径后,该函数将上下文的当前路径重置为空路径。

因此,当您致电CGContextStrokePath时,它无效,因为此时CGContext中的当前路径为空。

听起来你想在剪辑之前使用CGContextReplacePathWithStrokedPath。文档甚至提到了这个确切的用例:

  

例如,您可以通过调用此函数然后调用函数CGContextClip来剪切到路径的描边版本。

func drawBackgroundMask(context: CGContextRef,
                    center: CGPoint,
                    radius: CGFloat,
                    lineWidth: CGFloat,
                    startAngle: CGFloat,
                    endAngle: CGFloat) {
    let adjustedRadius: CGFloat = radius - (lineWidth/2) - 0

    CGContextSetLineWidth(context, lineWidth)
    CGContextSetLineCap(context, .Round)

    CGContextAddArc(context,
                    center.x,
                    center.y,
                    adjustedRadius,
                    startAngle,
                    endAngle,
                    0)

    CGContextReplacePathWithStrokedPath(context)
    CGContextClip(context)

    CGContextSetRGBFillColor(context, 100.0/255.0, 100.0/255.0, 100.0/255.0, 1.0);
    CGContextFillRect(context, rect);
}