UISlider: changed hight, but maximum value flashes

Viewed 743

I customised a UISlider and everything works well except when I drag the slider to 100%. Then the rounded caps are replaced with a square.

Here is how I customize the Slider:

@IBInspectable var trackHeight: CGFloat = 14

override func trackRect(forBounds bounds: CGRect) -> CGRect {
    return CGRect(origin: bounds.origin, size: CGSize(width: bounds.width, height: trackHeight))
}

98% image:

enter image description here

100% image:

enter image description here

3 Answers

Here some quick solution

You have changed frame of the line, the height is higher the default and that's why you see it.

You can move little bit slider at the 100%.

override func thumbRect(forBounds bounds: CGRect, trackRect rect: CGRect, value: Float) -> CGRect {
    var rect = super.thumbRect(forBounds: bounds, trackRect: rect, value: value)
    if value > 0.99 {
        rect = CGRect(x: rect.origin.x+2, y: rect.origin.y, width: rect.size.width, height: rect.size.height)
    }
    return rect
}

Or you can make the thumb bigger to cover the corners, its up to you.

Original answer here: Thumb image does not move to the edge of UISlider

updated to swift 4.2:

override func thumbRect(forBounds bounds: CGRect, trackRect rect: CGRect, value: Float) -> CGRect {
    let unadjustedThumbrect = super.thumbRect(forBounds: bounds, trackRect: rect, value: value)
    let thumbOffsetToApplyOnEachSide:CGFloat = unadjustedThumbrect.size.width / 2.0
    let minOffsetToAdd = -thumbOffsetToApplyOnEachSide
    let maxOffsetToAdd = thumbOffsetToApplyOnEachSide
    let offsetForValue = minOffsetToAdd + (maxOffsetToAdd - minOffsetToAdd) * CGFloat(value / (self.maximumValue - self.minimumValue))
    var origin = unadjustedThumbrect.origin
    origin.x += offsetForValue
    return CGRect(origin: origin, size: unadjustedThumbrect.size)
}

You can remove the track background by set minimumTrackTintColor and maximumTrackTintColor into UIColor.clear and draw the track background yourself.

For example:

class CustomSlider: UISlider {

    override func trackRect(forBounds bounds: CGRect) -> CGRect {
        return bounds
    }

    override func draw(_ rect: CGRect) {
        guard let context = UIGraphicsGetCurrentContext() else {
            return
        }

        context.setFillColor(UIColor.green.cgColor)
        let path = UIBezierPath(roundedRect: rect, cornerRadius: rect.size.height / 2).cgPath
        context.addPath(path)
        context.fillPath()
    }

}
Related