Search code examples
iosswiftcashapelayer

Make circle with slice cut out? iOS Swift 4


I'm trying to create a very simple colored circle inside a UIView with a slice cut out or in a different color, something like this:

enter image description here

I expected that this would be very simple and would only require a few lines of code since CAShapeLayer allows you to create all sorts of shapes. However, it seems that this is a lot more complicated than I thought since there barely any useful tutorials online on how to do this. Using third-party libraries for something as simple as this seems a bit overkill, so I prefer a solution with UIKit classes only. Any ideas? Thanks in advance!


Solution

  • According to this Thread after updating to swift 4 and editing to satisfy your needs ( Left the borders as an exercise =D )

    class ViewController: UIViewController {
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            let pieChart = PieChart(frame: CGRect(x: self.view.center.x, y: self.view.center.y, width: 300.0, height: 300.0))
            pieChart.backgroundColor = UIColor.clear
            self.view.addSubview(pieChart)
            pieChart.center = self.view.center
        }
    
    }
    
    class PieChart : UIView {
    
        override func draw(_ rect: CGRect) {
    
            drawSlice(rect, startPercent: 0, endPercent: 100, color: UIColor.gray)
            drawSlice(rect, startPercent: 30, endPercent: 65, color: UIColor.red)
        }
    
        private func drawSlice(_ rect: CGRect, startPercent: CGFloat, endPercent: CGFloat, color: UIColor) {
            let center = CGPoint(x: rect.origin.x + rect.width / 2, y: rect.origin.y + rect.height / 2)
            let radius = min(rect.width, rect.height) / 2
            let startAngle = startPercent / 100 * CGFloat(Double.pi) * 2 - CGFloat(Double.pi)
            let endAngle = endPercent / 100 * CGFloat(Double.pi) * 2 - CGFloat(Double.pi)
            let path = UIBezierPath()
            path.move(to: center)
            path.addArc(withCenter: center, radius: radius, startAngle: startAngle, endAngle: endAngle, clockwise: true)
            path.close()
            path.stroke()
            color.setFill()
            path.fill()
        }
    }
    

    enter image description here