Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to align UIBezierPath circle dashes

I am trying to draw a compass using UIBezierPath and adding dashes to the line to mark North, South, East, West directions and points in between. The dashes seem offset (they're not aligned), particularly in the North and South directions and the way I am doing it seems to add an extra dash when the path is closing.

let windCircleOrigin = CGPoint(x: self.center.x * 1.3, y: self.bounds.height / 2.0 - 10)
let windCircleRadius = CGFloat(self.bounds.height * 0.3)
let windCirclePath: UIBezierPath = UIBezierPath(arcCenter: windCircleOrigin, radius: windCircleRadius,startAngle: 0,  endAngle: CGFloat(M_PI) * 2.0, clockwise: true)
        windCirclePath.lineWidth = 6
let dashes: [CGFloat] = [windCirclePath.lineWidth * 0, windCirclePath.lineWidth * 3 ]
        windCirclePath.setLineDash(dashes, count: dashes.count
            , phase: 0.0)
UIColor.whiteColor().setFill()
UIColor.whiteColor().setStroke()
windCirclePath.stroke()
textView(self.windSpeedLabel! + " mph", x: windCircleOrigin.x - 20.0, y: windCircleOrigin.y - 8.0, color: UIColor.whiteColor(), width: 50.0, height: 20.0)
textView("N", x: windCircleOrigin.x - 7.0, y: windCircleOrigin.y - 70.0, color: UIColor.whiteColor(), width: 20, height: 20)
textView("S", x: windCircleOrigin.x - 7.0, y: windCircleOrigin.y + 50.0, color: UIColor.whiteColor(), width: 20, height: 20)
textView("W", x: windCircleOrigin.x - 70.0, y: windCircleOrigin.y - 8.0, color: UIColor.whiteColor(), width: 20, height: 20)
textView("E", x: windCircleOrigin.x + 60.0, y: windCircleOrigin.y - 8.0, color: UIColor.whiteColor(), width: 20, height: 20)

func textView(text: String, x: CGFloat, y: CGFloat, color: UIColor, width: CGFloat, height: CGFloat) {
    let textView = UILabel(frame: CGRectMake(x, y, width, height))
    textView.textAlignment = NSTextAlignment.Left
    textView.textColor = color
    textView.backgroundColor = UIColor.clearColor()
    textView.font = UIFont(name: "HelveticaNeue-Light", size: 12.0)
    textView.text = text
    self.addSubview(textView)
}

enter image description here

Without Dashes

like image 603
wxcoder Avatar asked Sep 05 '15 18:09

wxcoder


2 Answers

Instead, I would recommend drawing each tick individually. Then you can easily control their location.

Something like this:

let path = UIBezierPath()
let innerRadius: CGFloat = 50
let outerRadius: CGFloat = 60
let numTicks = 24

for i in 0..<numTicks {
    let angle = CGFloat(i) * CGFloat(2*M_PI) / CGFloat(numTicks)
    let inner = CGPoint(x: innerRadius * cos(angle), y: innerRadius * sin(angle))
    let outer = CGPoint(x: outerRadius * cos(angle), y: outerRadius * sin(angle))
    path.moveToPoint(inner)
    path.addLineToPoint(outer)
}

Then you can stroke this path with whatever lineWidth (and lineCapStyle) you want.

like image 86
jtbandes Avatar answered Nov 16 '22 10:11

jtbandes


Using a CGPath it is pretty easy. Not sure if the same can be done using UIBezierPath.

Swift 5.0

path.copy(dashingWithPhase: 0, lengths: [(.pi * radius) / dashCount])
like image 29
Jayden Irwin Avatar answered Nov 16 '22 11:11

Jayden Irwin