如何填充UIBezierPath中的重叠部分?

时间:2019-01-04 11:03:14

标签: swift uikit drawing uibezierpath

我想在其具有拐角的裁剪矩形周围绘制蒙版,并且我尝试使用组合UIBezierPath填充矩形内部,例如:4个圆和1个矩形,而不是将此路径分配给CAShapeLayer以将其用作子层在我看来。到目前为止,它可以填充所需的区域,只是重叠的部分(当在矩形上附加圆时)没有填充(所有角的四分之一三角形),所以我尝试使用combinedPath.usesEvenOddFillRule = false-combinedPath.fill()-combinedPath.close()但他们都没有与我合作!所以我需要填写这些部分,还有人可以帮助我吗?

您可以通过此link

查看图像

我的代码:

    // draw mask
    let path = UIBezierPath(rect: viewBackground.bounds)

    let maskRect = CGRect(x: imgView.frame.origin.x + roiRect.minX * rate, y: imgView.frame.origin.y + roiRect.minY * rate, width: roiRect.width * rate, height: roiRect.height * rate)
    // First apth is for rectangle
    let rectPath = UIBezierPath(rect: maskRect)
    path.append(rectPath)

    // and these paths for corners
    let cornerMaskCircleSize: CGFloat = circleSize/2
    let maskTopLeftCornerPath = UIBezierPath(ovalIn: CGRect(x: maskRect.minX - cornerMaskCircleSize/2, y: maskRect.minY - cornerMaskCircleSize/2, width: cornerMaskCircleSize, height: cornerMaskCircleSize))
    let maskTopRightCornerPath = UIBezierPath(ovalIn: CGRect(x: maskRect.maxX - cornerMaskCircleSize/2, y: maskRect.minY - cornerMaskCircleSize/2, width: cornerMaskCircleSize, height: cornerMaskCircleSize))
    let maskBottomRightCornerPath = UIBezierPath(ovalIn: CGRect(x: maskRect.maxX - cornerMaskCircleSize/2, y: maskRect.maxY - cornerMaskCircleSize/2, width: cornerMaskCircleSize, height: cornerMaskCircleSize))
    let maskBottomLeftCornerPath = UIBezierPath(ovalIn: CGRect(x: maskRect.minX - cornerMaskCircleSize/2, y: maskRect.maxY - cornerMaskCircleSize/2, width: cornerMaskCircleSize, height: cornerMaskCircleSize))

    // Combining all of them in one path
    path.append(maskTopLeftCornerPath)
    path.append(maskTopRightCornerPath)
    path.append(maskBottomRightCornerPath)
    path.append(maskBottomLeftCornerPath)
    path.usesEvenOddFillRule = true
    path.fill()
    path.close()

    cropMask.removeFromSuperlayer()
    cropMask.bounds = viewBackground.frame
    cropMask.position = viewBackground.center
    cropMask.path = path.cgPath
    cropMask.fillRule = .evenOdd
    cropMask.fillColor = UIColor.init(hexString: "#212f41").cgColor
    cropMask.opacity = 0.6

    viewBackground.layer.addSublayer(cropMask)

1 个答案:

答案 0 :(得分:0)

经过5个小时的研究,终于找到了extension,它用不同的方式解决了我的问题,此扩展有助于绘制四分之三的圆,因此我用它来绘制从矩形角侧空的圆。

这是用法示例代码:

fileprivate func drawMask() {

    let rectPath = UIBezierPath(rect: CGRect(x: 100, y: 200, width: 175, height: 150))
    let leftTopCornerPath = UIBezierPath(quarterCircleCentre: CGPoint(x: 100, y: 200), radius: 10, quadrant: .BottomRightThreeQuarterCircle)
    let rightTopCornerPath = UIBezierPath(quarterCircleCentre: CGPoint(x: 275, y: 200), radius: 10, quadrant: .BottomLeftThreeQuarterCircle)
    let leftBottomCornerPath = UIBezierPath(quarterCircleCentre: CGPoint(x: 100, y: 350), radius: 10, quadrant: .TopRightThreeQuarterCircle)
    let rightBottomCornerPath = UIBezierPath(quarterCircleCentre: CGPoint(x: 275, y: 350), radius: 10, quadrant: .TopLeftThreeQuarterCircle)

    let combined = UIBezierPath(rect: self.view.frame)
    combined.append(rectPath)
    combined.append(leftTopCornerPath)
    combined.append(rightTopCornerPath)
    combined.append(leftBottomCornerPath)
    combined.append(rightBottomCornerPath)

    let maskLayer = CAShapeLayer()
    maskLayer.bounds = self.view.bounds
    maskLayer.position = self.view.center
    maskLayer.path = combined.cgPath
    maskLayer.fillRule = .evenOdd
    maskLayer.fillColor = UIColor.black.cgColor
    maskLayer.opacity = 0.5

    self.view.layer.addSublayer(maskLayer)

}

扩展

extension UIBezierPath {


enum QuarterCircleQuadrant {
    case TopLeft, BottomLeft, TopRight, BottomRight, TopLeftThreeQuarterCircle, BottomRightThreeQuarterCircle, BottomLeftThreeQuarterCircle, TopRightThreeQuarterCircle
    var startAngle: CGFloat {
        switch self {
        case .BottomLeft:
            return CGFloat(Double.pi)
        case .BottomLeftThreeQuarterCircle:
            return CGFloat(Double.pi)
        case .TopLeft:
            return CGFloat(Double.pi)
        case .BottomRight:
            return 0
        case .TopRight:
            return 0
        case .TopRightThreeQuarterCircle:
            return 0
        case .TopLeftThreeQuarterCircle:
            return CGFloat(Double.pi)
        case .BottomRightThreeQuarterCircle:
            return 0
        }

    }
    var endAngle: CGFloat {
        switch self {
        case .BottomLeft:
            return CGFloat(Double.pi/2)
        case .BottomLeftThreeQuarterCircle:
            return CGFloat(Double.pi/2)
        case .TopLeft:
            return CGFloat(Double.pi) * 1.5
        case .BottomRight:
            return CGFloat(Double.pi/2)
        case .TopRight:
            return CGFloat(Double.pi) * 1.5
        case .TopRightThreeQuarterCircle:
            return CGFloat(Double.pi) * 1.5
        case .TopLeftThreeQuarterCircle:
            return CGFloat(Double.pi) * 1.5
        case .BottomRightThreeQuarterCircle:
            return CGFloat(Double.pi/2)
        }


    }

    var clockwise: Bool {
        switch self {
        case .BottomLeft:
            return false
        case .TopLeft:
            return true
        case .BottomRight:
            return true
        case .TopRight:
            return false
        case .BottomLeftThreeQuarterCircle:
            return true
        case .TopRightThreeQuarterCircle:
            return true
        case .TopLeftThreeQuarterCircle:
            return false
        case .BottomRightThreeQuarterCircle:
            return false
        }


    }

}

convenience init(quarterCircleCentre centre:CGPoint, radius:CGFloat, quadrant:QuarterCircleQuadrant)
{
    self.init()
    self.move(to: CGPoint(x: centre.x, y:centre.y))
    self.addArc(withCenter: centre, radius:radius, startAngle:quadrant.startAngle, endAngle: quadrant.endAngle, clockwise:quadrant.clockwise)
    self.close()
}
}

结果图片 link