I am trying to achieve this kind of slider to draw a line around the thumb in Swift an UIKit. This is what I am trying to achieve. Anyone can guide how can I achieve this or any CocoaPods I can use?
This is what I have achieved so far.
This is my code I have written to draw the curve:
private func drawCurvedLine() {
guard let context = UIGraphicsGetCurrentContext() else { return }
let trackRect = self.trackRect(forBounds: bounds)
let thumbRect = self.thumbRect(forBounds: bounds, trackRect: trackRect, value: value)
let startX = trackRect.minX - 5
let endX = trackRect.maxX + 5
let thumbCenterX = thumbRect.midX
let thumbCenterY = thumbRect.minY + 10 // Start of the thumb
let curveHeight: CGFloat = 20
let radius: CGFloat = 20 // Radius for the curve around the thumb
context.setStrokeColor(UIColor.black.cgColor)
context.setLineWidth(1.5)
// context.setLineCap(.round)
// Line before the curve
context.move(to: CGPoint(x: startX, y: thumbCenterY))
context.addLine(to: CGPoint(x: thumbCenterX - radius - 5, y: thumbCenterY))
// Curved line above the thumb
context.addCurve(to: CGPoint(x: thumbCenterX + radius + 5, y: thumbCenterY),
control1: CGPoint(x: thumbCenterX - radius, y: thumbCenterY - curveHeight),
control2: CGPoint(x: thumbCenterX + radius, y: thumbCenterY - curveHeight))
// Line after the curve
context.addLine(to: CGPoint(x: endX, y: thumbCenterY))
context.strokePath()
}
First imagine 4 line segments formed by 5 points, A to E, like this:
If you draw arcs that are tangent to each pair of these lines, you'd get something very similar to the desired result.
You can draw arcs like that with addArc(tangent1End:tangent2End:radius:)
. Just pass in the pairs of points, each pair at a time, i.e. B, C
, C, D
, D, E
.
Assuming rect
is the CGRect
in which we are drawing,
guard let context = UIGraphicsGetCurrentContext() else { return }
context.setStrokeColor(UIColor.black.cgColor)
context.setLineWidth(1.5)
// Try playing around with the parameters below :)
// this is the vertical distance between point C and the line BD
let curveHeight = 35.0
// this is the lenght of the line BD
let triangleWidth = 100.0
// radius of the arcs
let radius = 40.0
// the y coordinate of the points A, B, D, E
let y = rect.midY
// the slider's position along the x axis as a percentage
let percentage = 0.7
let pointA = CGPoint(x: rect.minX, y: y)
let pointB = CGPoint(x: (rect.width - triangleWidth) * percentage, y: y)
let pointC = CGPoint(x: (rect.width - triangleWidth) * percentage + triangleWidth / 2, y: y - curveHeight)
let pointD = CGPoint(x: (rect.width - triangleWidth) * percentage + triangleWidth, y: y)
let pointE = CGPoint(x: rect.maxX, y: y)
context.move(to: pointA)
context.addArc(tangent1End: pointB, tangent2End: pointC, radius: radius)
context.addArc(tangent1End: pointC, tangent2End: pointD, radius: radius)
context.addArc(tangent1End: pointD, tangent2End: pointE, radius: radius)
context.addLine(to: pointE)
context.strokePath()
The output looks like this: