Hemmelig
Hemmelig

Reputation: 794

Swift draw semicircle, not filled

I guess I am doing something horribly wrong, but I need to present you my idea. I want to draw something like a semicircle about 180 degrees, which has three different colours. But I don't want it to be filled out, I just want to have it the circle itself. I am using this code:

func addCirc(colour: UIColor, perc: CGFloat) {
    let center = CGPoint(x: 150, y:150)
    let radius = min(200, 200) / 2
    let startAngle = 0 / 100 * CGFloat(Double.pi) * 2 - CGFloat(Double.pi)
    let endAngle = perc / 100 * CGFloat(Double.pi) * 2 - CGFloat(Double.pi)
    let path = UIBezierPath()
    path.move(to: center)
    path.addArc(withCenter: center, radius: CGFloat(radius), startAngle: startAngle, endAngle: endAngle, clockwise: true)
    colour.setStroke()
    path.close()
    path.lineWidth = 20
    path.stroke()
}

let leftColour = UIColor.red
let middleColour = UIColor.yellow
let rightColour = UIColor.green
addCirc(colour: rightColour, perc: 50)
addCirc(colour: middleColour, perc: 30)
addCirc(colour: leftColour, perc: 10)

The result looks like the following: enter image description here

So I just want to have the circle itself and delete the bottom line and the diagonal ones. I guess it's wrong to use addArc in this situation. Does anybody know an alternative to solve it?

Upvotes: 1

Views: 4583

Answers (1)

Sweeper
Sweeper

Reputation: 271260

I think the call to path.close is making all those straight lines appear. If you just want one single arc and nothing else, why not try the initializer init(arcCenter:radius:startAngle:endAngle:clockwise:)?

class MyView: UIView {
    override func draw(_ rect: CGRect) {
        let path = UIBezierPath(arcCenter: CGPoint(x: 100, y: 70), radius: 50, startAngle: -CGFloat.pi, endAngle: 0, clockwise: true)
        UIColor.black.setStroke()
        path.lineWidth = 10
        path.stroke()
    }
}

You can create something like this:

enter image description here

If you want different parts of the arc to be different colors, you probably want to remember the angle where the previous part of the arc ends (i.e. store the angle in a variable). You doesn't seem to be doing this at the moment.

Here's what I've been able to come up with:

override func draw(_ rect: CGRect) {
    var lastArcAngle = -CGFloat.pi
    func addArc(color: UIColor, percentage: CGFloat) {
        let fullCircle = CGFloat.pi * 2
        let arcAngle = fullCircle * percentage
        let path = UIBezierPath(arcCenter: CGPoint(x: 100, y: 70), radius: 50, startAngle: lastArcAngle, endAngle: lastArcAngle + arcAngle, clockwise: true)
        color.setStroke()
        path.lineWidth = 10
        path.stroke()
        lastArcAngle += arcAngle
    }
    addArc(color: .red, percentage: 1.0 / 6.0)
    addArc(color: .green, percentage: 1.0 / 6.0)
    addArc(color: .blue, percentage: 1.0 / 6.0)
}

Upvotes: 5

Related Questions