Sahil Manchanda
Sahil Manchanda

Reputation: 10012

Draw a diagonal line with side curves UIBezierPath

I want to draw diagonal line with side curves like the following enter image description here

Code:

func drawCanvas1(frame: CGRect = CGRect(x: 0, y: 0, width: 240, height: 120)) {

        //// Bezier Drawing
        let bezierPath = UIBezierPath()
        UIColor.black.setStroke()
        bezierPath.lineWidth = 1
        bezierPath.stroke()


        //// Bezier 2 Drawing
        let bezier2Path = UIBezierPath()
        bezier2Path.move(to: CGPoint(x: frame.minX + 0.5, y: frame.minY + 103.42))
        bezier2Path.addCurve(to: CGPoint(x: frame.minX + 12.17, y: frame.minY + 119.5), controlPoint1: CGPoint(x: frame.minX + 0.5, y: frame.minY + 103.42), controlPoint2: CGPoint(x: frame.minX + 0.5, y: frame.minY + 119.5))
        bezier2Path.addCurve(to: CGPoint(x: frame.minX + 232.03, y: frame.minY + 26.23), controlPoint1: CGPoint(x: frame.minX + 23.85, y: frame.minY + 119.5), controlPoint2: CGPoint(x: frame.minX + 232.03, y: frame.minY + 26.23))
        bezier2Path.addCurve(to: CGPoint(x: frame.minX + 237.87, y: frame.minY + 0.5), controlPoint1: CGPoint(x: frame.minX + 232.03, y: frame.minY + 26.23), controlPoint2: CGPoint(x: frame.minX + 243.7, y: frame.minY + 16.58))
        UIColor.black.setStroke()
        bezier2Path.lineWidth = 1
        bezier2Path.lineCapStyle = .square
        bezier2Path.stroke()

        let layer1 = CAShapeLayer()
        layer1.path = bezierPath.cgPath

        let layer2 = CAShapeLayer()
        layer2.path = bezier2Path.cgPath

        imageCollectionView.layer.addSublayer(layer1)
        imageCollectionView.layer.addSublayer(layer2)

    }

output:

enter image description here

As you can see in output it is filling with black color whereas I've only given stroke. I'm not really good at bezier path. can anyone help me in getting the desired effect

Upvotes: 3

Views: 975

Answers (2)

Bill
Bill

Reputation: 469

Maybe using addArc is easier?

func drawCanvas1(frame: CGRect = CGRect(x: 0, y: 0, width: 240, height: 120)) {
    let rhsY:CGFloat = frame.minY + 60   // Please adjust this value depending on your need
    let cornerRadius:CGFloat = 25
    let angle = atan2(frame.maxY - rhsY, frame.width)

    // upper left corner
    let p1 = CGPoint(x: frame.minX, y: frame.minY)
    // left point touching bottom left corner
    let p2 = CGPoint(x: frame.minX, y: frame.maxY - cornerRadius)
    let a = cornerRadius * cos(angle)
    let o = cornerRadius * sin(angle)

    // Center of bottom left round corner
    let c1 = CGPoint(x: p2.x + a, y: p2.y - o)
    let c1Start = CGFloat.pi - angle
    let c1End = c1Start - (CGFloat.pi / 2)

    // Center of bottom right round corner
    let c2 = CGPoint(x: frame.maxX - cornerRadius, y: rhsY)

    // bottom point touching bottom left corner
//    let p3 = CGPoint(x: c1.x + o, y: c1.y + a)
    // bottom point touching bottom right corner
    let p4 = CGPoint(x: c2.x + o, y: c2.y + a)
    // right point touching bottom right corner
//    let p5 = CGPoint(x: frame.maxX, y: rhsY)
    // upper right corner
    let p6 = CGPoint(x: frame.maxX, y: frame.minY)

    let path = UIBezierPath()
    path.move(to: p1)
    path.addLine(to: p2)
    path.addArc(withCenter: c1, radius: cornerRadius, startAngle: c1Start, endAngle: c1End, clockwise: false)
    path.addLine(to: p4)
    path.addArc(withCenter: c2, radius: cornerRadius, startAngle: c1End, endAngle: 0, clockwise: false)
    path.addLine(to: p6)
    path.addLine(to: p1)

    // I am guessing you are trying to use a mask to the top level image?
    let maskLayer = CAShapeLayer()
    maskLayer.path = path.cgPath
    imageCollectionView.layer.mask = maskLayer
}

Upvotes: 2

Subash thapa
Subash thapa

Reputation: 57

Unless you provide your fill color, black is used by default to fill the path. If the path is not closed, fill color tries to fill using start and end points.

Upvotes: 0

Related Questions