How To Make a Custom Control Tutorial: A Reusable Slider

Controls are the bread and butter of iOS apps. UIKit provides many but this tutorial shows you how to make an iOS custom control in Swift. By Lea Marolt Sonnenschein.

4.6 (18) · 3 Reviews

Download materials
Save for later
Share
Update note: Lea Marolt Sonnenschein updated this tutorial for iOS 12, Xcode 10 and Swift 4.2. Colin Eberhardt wrote the original.

User interface controls are one of the most important building blocks of any application. They serve as the graphical components that allow users to view and interact with your application. Apple supplies a set of controls, such as UITextField, UIButton and UISwitch. Armed with this toolbox of pre-existing controls, you can create a great variety of user interfaces.

However, sometimes you need to do something a little bit different; something that the stock controls can’t handle quite the way you want.

An iOS custom control is nothing more than a control that you have created yourself. Custom controls, like standard controls, should be generic and versatile. You’ll find there’s an active and vibrant community of developers who love to share their iOS custom control creations provided they’re both of these things.

In this tutorial, you’ll implement a RangeSlider iOS custom control. This control is like a double-ended slider that lets you pick both a minimum and maximum value. You’ll touch on such concepts as extending existing controls, designing and implementing your control’s API and even how to share your new control with the development community.

Time to start customizing!

Getting Started

Use the Download Materials button at the top or bottom of this tutorial to download the starter project.

Say you’re developing an application for searching property-for-sale listings. This fictional application allows the user to filter search results so that they fall within a certain price range.

You could provide an interface that presents the user with a pair of UISlider controls, one for setting the maximum price and one for setting the minimum price. However, this interface doesn’t help the user visualize the price range. It would be much better to present a single slider with two thumbs to indicate the high and low price range for their search criteria.

good vs bad slider design

You could build this range slider by subclassing UIView and creating a bespoke view for visualizing price ranges. That would be fine for the context of your app — but it would be a struggle to port it to other apps.

It’s a much better idea to make this new component as generic as possible so that you can reuse it later. This is the very essence of custom controls.

The first decision you need to make when creating an iOS custom control is which existing class to subclass or extend to make the new control.

Your class must be a UIView subclass for it to be available in the application’s UI.

If you check Apple’s UIKit reference, you’ll see that a number of the framework controls such as UILabel and UIWebView subclass UIView directly. However, there are a handful, such as UIButton and UISwitch which subclass UIControl, as shown in the hierarchy below:

ios uiview and uicontrol class

Note: For a complete class hierarchy of UI components, check out the UIKit Framework Reference.

In this tutorial, you’ll subclass UIControl.

Open the starter project in Xcode. You’ll put your slider control code in RangeSlider.swift. Before you write any code for your control, though, add it to the view controller so that you can watch its evolution.

Open ViewController.swift and replace its contents with the following:

import UIKit

class ViewController: UIViewController {
  let rangeSlider = RangeSlider(frame: .zero)
  
  override func viewDidLoad() {
    super.viewDidLoad()
    
    rangeSlider.backgroundColor = .red
    view.addSubview(rangeSlider)
  }
  
  override func viewDidLayoutSubviews() {
    let margin: CGFloat = 20
    let width = view.bounds.width - 2 * margin
    let height: CGFloat = 30
    
    rangeSlider.frame = CGRect(x: 0, y: 0,
                               width: width, height: height)
    rangeSlider.center = view.center
  }
}

This code creates an instance of your control in the given frame and adds it to the view. It also sets the background color to red so that the control is visible on the screen.

Build and run your app. You should see something similar to the following:


Screenshot #1, Slider is a red rectangle.

Before you add the visual elements to your control, you’ll need a few properties to keep track of the state of your control. This will form the start of your control’s Application Programming Interface, or API for short.

Note: Your control’s API defines the methods and properties that you decide to expose to the other developers who will use your control.

Adding Default Control Properties

Open RangeSlider.swift and replace the code with the following:

import UIKit

class RangeSlider: UIControl {
  var minimumValue: CGFloat = 0
  var maximumValue: CGFloat = 1
  var lowerValue: CGFloat = 0.2
  var upperValue: CGFloat = 0.8
}

These four properties are all you need to describe the state of this control. You provide the maximum and minimum values for the range, along with the upper and lower values set by the user.

Well-designed controls should define some default property values or else your control will look strange when it draws on the screen.

Now it’s time to work on the interactive elements of your control: namely, the thumbs to represent the high and low values and the track on which the thumbs will slide.

CoreGraphics vs. Images

There are two primary ways that you can render controls on-screen:

  1. CoreGraphics: Render your control using a combination of layers and CoreGraphics.
  2. Images: Create images that represent the various elements of your control.

There are pros and cons to each technique, as outlined below:

Using Core Graphics, you can parameterize every feature of your control, such as colors, border thickness, and curvature — pretty much every visual element that goes into drawing your control!

Using images provides the most flexibility to developers who will use your control. Developers can change every pixel and every detail of your control’s appearance, but this requires exceptional graphic design skills — and it’s difficult to modify the control from code.

  • Core Graphics: Constructing your control using Core Graphics means that you have to write the rendering code yourself, which requires more effort. However, this technique allows you to create a more flexible API.
  • Images: Constructing your control using images is probably the simplest option for authoring the control. If you want other developers to be able to change the look and feel of your control, you need to expose these images as UIImage properties.

In this tutorial, you’ll use a bit of both. You’ll use images to render the thumbs and CoreGraphics to render the track layer.

Note: Interestingly, Apple also tends to opt for using images in their controls. This is most likely because they know the size of each control and don’t tend to want to allow too much customization. After all, they want all apps to end up with a similar look-and-feel.