I'm attempting to draw a line with a UIBezierPath
that alternates between dots and dashes. Here's my code so far:
func drawAlternatingDashesAndDots() {
let path = UIBezierPath()
path.move(to: CGPoint(x: 10,y: 10))
path.addLine(to: CGPoint(x: 290,y: 10))
path.lineWidth = 8
let dots: [CGFloat] = [0.001, path.lineWidth * 2]
path.setLineDash(dots, count: dots.count, phase: 0)
for i in 0...10 {
if i % 2 == 0 {
// Even Number
path.lineCapStyle = CGLineCap.round
} else {
// Odd Number
path.lineCapStyle = CGLineCap.square
}
}
UIGraphicsBeginImageContextWithOptions(CGSize(width:300, height:20), false, 2)
UIColor.white.setFill()
UIGraphicsGetCurrentContext()!.fill(.infinite)
UIColor.black.setStroke()
path.stroke()
let image = UIGraphicsGetImageFromCurrentImageContext()
dashDotDashLineView.image = image
UIGraphicsEndImageContext()
}
However, in my image view, only dots are rendered:
I'm probably misunderstanding something about how UIBezierPath
works; any help appreciated!
The UIBezierPath
documentation explains the meaning of the pattern
argument:
A C-style array of floating point values that contains the lengths (measured in points) of the line segments and gaps in the pattern. The values in the array alternate, starting with the first line segment length, followed by the first gap length, followed by the second line segment length, and so on.
In your code, 0.001
is the first value in the pattern, so it is a line segment length, and is small enough to be drawn as a dot. The second value in the pattern is path.lineWidth * 2
, so it is a gap length, which is the distance between the dots.
If you want to alternate dots and dashes, you have to pass a pattern containing four numbers: a line segment length, a gap, another line segment length, and another gap.
let dots: [CGFloat] = [
0.001, // dot
path.lineWidth * 2, // gap
path.lineWidth * 2, // dash
path.lineWidth * 2, // gap
]