Search code examples
iosswiftswift3geometryuibezierpath

UIBezierPath Creating Triangle,Square,Circle Swift


I am attempting to create three shapes: a Circle, Square & Triangle. I have created the circle & square, but am unable to create the triangle. My biggest issue is to keep all three shapes in the center of the screen. The circle and square are fine, but when I attempt to make the triangle it does not work. I am also trying to make the triangle look like a "play button" so that the "tip" of the triangle is facing to the right. Here is the code.

func trainglePathWithCenter(center: CGPoint, side: CGFloat) -> UIBezierPath {
    let path = UIBezierPath()

    let startX = center.x - side / 2
    let startY = center.y - side / 2

   path.move(to: CGPoint(x: startX, y: startY))
    path.addLine(to: CGPoint(x: startX, y: startY - side))
    path.addLine(to: CGPoint(x: startX + side, y: startY + side/2))
    path.close()

    return path
}


func circlePathWithCenter(center: CGPoint, radius: CGFloat) -> UIBezierPath {
    let circlePath = UIBezierPath()
    circlePath.addArc(withCenter: center, radius: radius, startAngle: -CGFloat(M_PI), endAngle: -CGFloat(M_PI/2), clockwise: true)
    circlePath.addArc(withCenter: center, radius: radius, startAngle: -CGFloat(M_PI/2), endAngle: 0, clockwise: true)
    circlePath.addArc(withCenter: center, radius: radius, startAngle: 0, endAngle: CGFloat(M_PI/2), clockwise: true)
    circlePath.addArc(withCenter: center, radius: radius, startAngle: CGFloat(M_PI/2), endAngle: CGFloat(M_PI), clockwise: true)
    circlePath.close()
    return circlePath
}

func squarePathWithCenter(center: CGPoint, side: CGFloat) -> UIBezierPath {
    let squarePath = UIBezierPath()
    let startX = center.x - side / 2
    let startY = center.y - side / 2

    squarePath.move(to: CGPoint(x: startX, y: startY))

    squarePath.addLine(to: squarePath.currentPoint)
    squarePath.addLine(to: CGPoint(x: startX + side, y: startY))
    squarePath.addLine(to: squarePath.currentPoint)
    squarePath.addLine(to: CGPoint(x: startX + side, y: startY + side))
    squarePath.addLine(to: squarePath.currentPoint)
    squarePath.addLine(to: CGPoint(x: startX, y: startY + side))
    squarePath.addLine(to: squarePath.currentPoint)
    squarePath.close()
    return squarePath

}

Where am I going wrong with the geometry for the triangle?


Solution

  • You subtracted when you need to add. Remember, +Y is down.

    Change:

    path.addLine(to: CGPoint(x: startX, y: startY - side))
    

    To:

    path.addLine(to: CGPoint(x: startX, y: startY + side))
    

    Here it is running in a Playground:

    Triangle demo running in a Playground


    Here's the full code for the Playground demo:

    class Custom: UIView {
        override func draw(_ rect: CGRect) {
            let path = trainglePathWithCenter(center: self.center, side: self.bounds.width / 2)
    
            path.stroke()
        }
    
        func trainglePathWithCenter(center: CGPoint, side: CGFloat) -> UIBezierPath {
            let path = UIBezierPath()
    
            let startX = center.x - side / 2
            let startY = center.y - side / 2
    
            path.move(to: CGPoint(x: startX, y: startY))
            path.addLine(to: CGPoint(x: startX, y: startY + side))
            path.addLine(to: CGPoint(x: startX + side, y: startY + side/2))
            path.close()
    
            return path
        }
    }
    
    let custom = Custom(frame: CGRect(x: 0, y: 0, width: 200, height: 200))
    custom.backgroundColor = .white