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

3

我有一条弧线,它是这样画的:

    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)

}

将上述代码注释掉后,我可以创建下面的内容:

黑色弧形

然而,如果我试图通过取消上面两行代码的注释并将背景涂成纯色来使用绘制的形状作为遮罩,则会得到不同的结果:

    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个回答

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);
}

谢谢,这非常有帮助!这可能会帮助其他人:对于那些想要在图形上下文中继续执行更多“未剪切”操作的人,请使用context.resetClip() - Bocaxica

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