UIBezierPath 附加重叠未填充

Posted

技术标签:

【中文标题】UIBezierPath 附加重叠未填充【英文标题】:UIBezierPath appending overlapping isn't filled 【发布时间】:2017-08-27 09:07:29 【问题描述】:

我正在尝试使用UIBezierPath.append 合并两个重叠的 UIBezierPath,并且我希望填充重叠的空间。我尝试将usesEvenOddFillRule 属性设置为false,但仍然无法填充。这是问题的最小示例:

override func draw(_ rect: CGRect) 
    let firstShape = UIBezierPath()

    firstShape.move(to: CGPoint(x: 100, y: 100))
    firstShape.addLine(to: CGPoint(x: 100, y: 150))
    firstShape.addLine(to: CGPoint(x: 150, y: 170))
    firstShape.close()

    let secondShape = UIBezierPath(rect: CGRect(x: 125, y: 125, width: 75, height: 75))

    let combined = UIBezierPath()
    combined.append(firstShape)
    combined.append(secondShape)

    UIColor.black.setFill()
    combined.fill()

这会产生以下形状:

我希望它是什么样子:

在一个 UIBezierPath 上使用move(to: CGPoint) 时似乎也会出现此问题。如果你在同一个 UIBezierPath 上绘制这两个形状,就会出现同样的问题。

有谁知道如何填充重叠区域?最好该解决方案在执行addClip()

时也可以使用

【问题讨论】:

【参考方案1】:

您将usesEvenOddFillRule 设置为false 是正确的。除此之外,您需要确保您的形状都以相同的方向(顺时针或逆时针)绘制。

我在绘制三角形时颠倒了你addLines的顺序来反转它。

override func draw(_ rect: CGRect) 
    let firstShape = UIBezierPath()

    firstShape.move(to: CGPoint(x: 100, y: 100))
    firstShape.addLine(to: CGPoint(x: 150, y: 170))
    firstShape.addLine(to: CGPoint(x: 100, y: 150))
    firstShape.close()

    let secondShape = UIBezierPath(rect: CGRect(x: 125, y: 125, width: 75, height: 75))

    let combined = UIBezierPath()
    combined.append(firstShape)
    combined.append(secondShape)
    combined.usesEvenOddFillRule = false

    UIColor.black.setFill()
    combined.fill()

【讨论】:

usesEvenOddFillRule 默认为 false。是否需要显式设置? @Fitsyu,如果你知道它已经设置好了,你不必明确设置它。 如果你看到你的重叠空间没有被填满,你也可以使用 secondShape.reversed()。 如果我应用描边颜色,这不起作用,它适用于我添加的每个形状【参考方案2】:

在关闭第一个形状之前调用填充:

firstShape.fill()
firstShape.close()

【讨论】:

我需要稍后在代码中使用合并的路径作为剪辑,所以很遗憾这不是问题的解决方案

以上是关于UIBezierPath 附加重叠未填充的主要内容,如果未能解决你的问题,请参考以下文章

UIBezierPath 填充与 CAShapeLayer

如何使 UIBezierPath 从中心填充

如何为 UIBezierPath 上的填充颜色变化设置动画?

如何以给定的顺序动画/填充 UIBezierPath?

UIBezierPath + CAShapeLayer - 填充一个圆圈的动画[重复]

iOS 11 PDFKit 墨水注释 - 无法填充 UIBezierPath