How to implement custom UISlider in swift

User interface controls are very important part of any application.  Apple provides a variety of controls for you to use, such as UIButton, UISwitch, UISlider and so on.  Using this tool box of pre-existing controls, you can create a great deal of fairly functional apps.

However, the industry is evolving fast and designers came up with new ideas to improve user experience. Or you might need a bit different functional behavior for your control. At that point, existing tools are not enough. I first met this case when develop the Postys app.

In this tutorial we will dive into UISlider object. 

A UISlider is a visual control used to select a single value from a continuous range of values. An indicator or thumb, notes the current value of slider and can be moved by the user to change the setting.

So let’s play with it.

GETTING STARTED

Open up Xcode and let’s create a new project from Single View Application template ( File/new/project + iOS/Application/Single View Application ). Enter a name for your project as the product name, choose organization name and organization identifier. Make sure that Swift is selected as the language, iPhone as device and that Use Core Data is not selected. Choose a place to save the project and hit Create.

First let’s add UISlider to our app so we have something to play with. Add UISlider and UILabel to your story board. Then link your story board properties to the code. Finally let’s add @IBAction to change label’s text to display current value for slider. So far your ViewController.swift file should look something like this:

import UIKit

class ViewController: UIViewController {
    
    @IBOutlet weak var slider: UISlider!
    @IBOutlet weak var label: UILabel!
    
    override func viewDidLoad() {
        super.viewDidLoad()
    }
    
    @IBAction func sliderValueDidChanged(sender: UISlider) {
        let currentValue = sender.value   
        label.text = "\(currentValue)"
    }
}

Build and run your app, you should see something very similar to the following:

how_to_customize_uislider.png

As you might notice I have added some constraints and your layout likely differs but it doesn't matter in our case. Or simply grab starter project here.

start customizing

There are two ways to render your slider on screen:

  1.  Images – apply images that represent various elements of your slider.
  2. CoreGraphics – Describe elements using CoreGraphics and Layers.

images way

Apple tend to opt images in their controls and you can find out how to change slider appearance using images in UISlider Class Reference. It's always nice to dive into docs first.

Let’s play with images. Add the following lines into your viewDidLoad() method in VeiwController.swift:

slider.minimumTrackTintColor = UIColor.yellowColor()
slider.minimumValue = 1
slider.maximumValue = 10

// I also added some background and label color changes
view.backgroundColor = UIColor.darkGrayColor()
label.textColor = UIColor.lightTextColor()

The code above is pretty straightforward, it sets range of values and minimumTrackTintColor. If you build and run project at this point you might notice our slider is not enough extraordinary, is it?

So I came up with new thumb image for our slider (Download it here). Obviously you can use any image you want. Finally import icon to your Xcode project and insert just one line of code in viewDidLoad below lines where we previously set values and tint color:

slider.setThumbImage(UIImage(named: "triangle")!, forState: .Normal)

Build and run your app. Viola! 

how-to-customize-uislider

How do you like it ? With just few lines of code and one simple icon we changed appearance of our slider quite a lot. You can download Xcode project up to this point here.

You may noticed my icon contains a bunch of empty space. It is an interim decision, you better override thumbRectForBounds(_:trackRect:value:) to properly position thumb image. Ok, we have somewhat custom slider, but how about adding ticks? Custom gestures? Proceed to the second part of the tutorial to figure this out!