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

Aro*_*n C 3 core-graphics ios swift

我有一个弧线,我绘制如下:

    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)

}
Run Code Online (Sandbox Code Playgroud)

注释掉以上几行后,我可以创建以下内容:

黑弧

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

    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);
}
Run Code Online (Sandbox Code Playgroud)

作为面具

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

Kur*_*vis 5

在您的第二个示例中,剪辑仅考虑圆弧的路径。各种笔画参数(如线宽、上限等)仅在您实际绘制路径时使用,而您并未这​​样做。

首先在 中设置路径CGContext,然后剪辑它。上下文中的路径随后被消耗。正如文档所说:

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

所以当你调用 时 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);
}
Run Code Online (Sandbox Code Playgroud)