Search code examples
iosswiftuislider

How to make a custom UISlider iOS?


Hello I have a version of a desired style of UISlider implemented in android. enter image description here

It was not a trivial task to implement. Now I want the same slider in iOS. I wonder if there a solution not to draw all the slider from scratch? Or any advise. Thank you.


Solution

  • You'll have to do a bit of work, but you shouldn't need to build a complete solution from scratch.

    Adding your labels will be trivial - pretty basic usage of UISlider

    "Stretching" a track image (or tint color) left and right of center as your animation shows will be a little tricky, as the UISlider control has only a track / background image and a "current" image that stretches on the left-hand side.

    One approach would be to set the UISlider track images to transparent or hidden and then "overlay" the slider on top of your "full line" and your "blue line". When the slider value changes (as it is dragged), change the frame of the blue line.

    Using auto-layout and constraints would make that pretty straight-forward.

    Edit: A really quick example. The "thumb" is purposefully moved below the "custom slider bar" to show the images...

    enter image description here

    And, this is the code to get that:

    import UIKit
    
    class SliderViewController: UIViewController {
    
        // @IBOutlets needed, but I'm just showing the "code" here
        // ...
    
        @IBAction func sliderValueChanged(_ sender: Any) {
    
            if let s = sender as? UISlider {
                updateSlider(pct: CGFloat(s.value))
            }
    
        }
    
        func updateSlider(pct: CGFloat) -> Void {
    
            let p = (pct - 0.5) * 2.0
    
            theValueLabel.text = String(format: "%0.1f", p * 10)
    
            leftSideValueWidth.constant = p >= 0.0 ? 0.0 : (leftSideHolderView.frame.size.width * (-p))
            rightSideValueWidth.constant = p >= 0.0 ? (rightSideHolderView.frame.size.width * p) : 0.0
    
        }
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            // init slider to center
            updateSlider(pct: 0.5)
    
            // set default left- and right-side "track" images to empty images
            theSlider.setMinimumTrackImage(UIImage(), for: .normal)
            theSlider.setMaximumTrackImage(UIImage(), for: .normal)
    
        }
    
    }
    

    Black UIView for the frame... Gray UIView for the "slider bar"... two transparent UIView for the left- / right- side framing... two blue UIView - one for each side. And a standard UISlider control. That's about it.

    You could also set a custom Thumb image, if the default one is too big for your needs.