Search code examples
swiftpie-chartuibezierpath

Filling UIBezierPath to create pie chart


I'm trying to create a pie chart using UIBezierPath.

The problem is that when filled, instead of the end points joining at the centre they are joined to each other like this:

enter image description here

  func progressCircle() -> CALayer { 
        let progressCircle = CAShapeLayer()
        
        let pi : CGFloat = .pi
        let rect = CGRect(x: 0, y: 0, width: 50, height: 50)
        let radius = rect.width/2
        
        let phaseShift = 1/2*pi
        let current : CGFloat = 70.0//currentCount
        let total : CGFloat = 100.0//total
        let startAngle : CGFloat = 0 - phaseShift
        let endAngle = (2 * pi * current/total) - phaseShift
        

        progressCircle.path = UIBezierPath(arcCenter: CGPoint(x: rect.midX, y: rect.midY), radius:radius , startAngle: startAngle, endAngle: endAngle, clockwise: true).cgPath
        progressCircle.fillColor = UIColor.red.cgColor
        

        return progressCircle
    }

Solution

  • That's normal behavior since you are using UIBezierPath(arcCenter:radius:startAngle:endAngle:clockwise:). You don't tell your path to go back to center.

    Instead, draw it yourself.

    Commented line aren't necessary, but might help you see what's going on.

    let bezierPath = UIBezierPath()
    let center = CGPoint(x: rect.midX, y: rect.midY)
    bezierPath.move(to: center)
    //bezierPath.addLine(to: CGPoint(x: center.x + radius * cos(startAngle), y: center.y + radius * sin(startAngle)))
    bezierPath.addArc(withCenter: center, radius: radius, startAngle: startAngle, endAngle: endAngle, clockwise: true)
    //bezierPath.addLine(to: CGPoint(x: center.x + radius * cos(endAngle), y: center.y + radius * sin(endAngle)))
    bezierPath.addLine(to: center)
    bezierPath.close()
    

    Of course, that's bad ASCII art, but you see the 3 "+", these are the center, and the two commented line points for record. The line between the center and these point is implicit, if you want to implicit them, uncomment the line.

         +-
         |  `
         |   `
    +----+   )
    `.       '
     `.     '
      `- - -