Skip to content

UISwitch

UISwitch is a UIKit control that allows users to toggle between two states, typically on and off, in an iOS app. It is a subclass of UIControl and is commonly used for enabling or disabling features, such as settings toggles. This document covers the key properties, methods, and usage of UISwitch, along with examples and best practices.

Overview of UISwitch

A UISwitch is a simple, binary control that displays a thumb that slides between an "on" and "off" position. It is ideal for settings where a user needs to make a straightforward yes/no or true/false choice. The switch provides visual feedback and supports customization of its appearance and behavior.

Creating a UISwitch

You can create a UISwitch programmatically or via Interface Builder (storyboards/xibs).

Programmatic Example:

swift
import UIKit

let switchControl = UISwitch()
switchControl.isOn = true
switchControl.addTarget(self, action: #selector(switchValueChanged(_:)), for: .valueChanged)
view.addSubview(switchControl)

Key Properties of UISwitch

Below are the most commonly used properties of UISwitch:

PropertyTypeDescription
isOnBoolIndicates whether the switch is in the "on" state (true) or "off" state (false).
onTintColorUIColor?The color of the switch’s background when in the "on" state.
thumbTintColorUIColor?The color of the thumb.
onImageUIImage?An optional image displayed in the "on" state (iOS 14+).
offImageUIImage?An optional image displayed in the "off" state (iOS 14+).
isEnabledBoolWhether the switch is enabled (affects appearance and interaction).

Example: Configuring Properties:

swift
switchControl.isOn = false
switchControl.onTintColor = .systemGreen
switchControl.thumbTintColor = .white
switchControl.isEnabled = true

Key Methods of UISwitch

UISwitch inherits methods from UIControl and UIView, but also provides switch-specific methods:

MethodDescription
setOn(_:animated:)Sets the switch’s state to on or off, optionally animating the transition.

Example: Toggling Programmatically:

swift
switchControl.setOn(true, animated: true)

Handling User Interaction

To respond to state changes, add a target-action for the .valueChanged event.

Example:

swift
switchControl.addTarget(self, action: #selector(switchValueChanged(_:)), for: .valueChanged)

@objc func switchValueChanged(_ sender: UISwitch) {
    print("Switch is \(sender.isOn ? "on" : "off")")
}

Customizing Appearance

Tint Colors

  • Use onTintColor to set the background color when the switch is on.
  • Use thumbTintColor to set the thumb’s color.

Example:

swift
switchControl.onTintColor = .systemBlue
switchControl.thumbTintColor = .systemGray6

Custom Images (iOS 14+)

You can set custom images for the "on" and "off" states using onImage and offImage. These images are displayed in the switch’s background.

Example:

swift
switchControl.onImage = UIImage(systemName: "checkmark.circle.fill")
switchControl.offImage = UIImage(systemName: "xmark.circle.fill")

Notes:

  • Images should be small and appropriately sized to fit within the switch’s bounds.
  • Use SF Symbols or custom images with a transparent background for best results.

Best Practices

  • Use Clear Context: Pair the switch with a label to clarify its purpose (e.g., "Enable Notifications").

  • Support Accessibility: Set accessibilityLabel and accessibilityValue for VoiceOver.

    swift
    switchControl.accessibilityLabel = "Notifications toggle"
    switchControl.accessibilityValue = switchControl.isOn ? "On" : "Off"
  • Use Auto Layout: Set translatesAutoresizingMaskIntoConstraints = false and use constraints (e.g., with SnapKit).

  • Provide Feedback: Update the UI or save the state when the switch changes.

  • Test on Devices: Verify switch behavior and appearance on various screen sizes and iOS versions.

Troubleshooting

  • Switch Not Responding: Ensure isEnabled = true and the target-action is set for .valueChanged.
  • Appearance Issues: Check iOS version compatibility for properties like onImage or thumbTintColor.
  • Accessibility Issues: Test with VoiceOver to ensure accessibilityValue updates dynamically.
  • Layout Problems: Verify constraints or frame size, as switches have a fixed intrinsic size.

Example: Complete UISwitch Setup

swift
import UIKit
import SnapKit

class ViewController: UIViewController {
    let switchControl = UISwitch()
    let statusLabel = UILabel()

    override func viewDidLoad() {
        super.viewDidLoad()
        
        // Configure switch
        switchControl.isOn = true
        switchControl.onTintColor = .systemGreen
        switchControl.thumbTintColor = .white
        switchControl.addTarget(self, action: #selector(switchValueChanged(_:)), for: .valueChanged)
        
        // Configure label
        statusLabel.text = "Switch is On"
        statusLabel.textAlignment = .center
        
        // Accessibility
        switchControl.accessibilityLabel = "Feature toggle"
        switchControl.accessibilityValue = switchControl.isOn ? "On" : "Off"
        
        view.addSubview(switchControl)
        view.addSubview(statusLabel)
        
        // Auto Layout with SnapKit
        switchControl.snp.makeConstraints { make in
            make.centerX.equalToSuperview()
            make.top.equalTo(view.safeAreaLayoutGuide).offset(20)
        }
        
        statusLabel.snp.makeConstraints { make in
            make.centerX.equalToSuperview()
            make.top.equalTo(switchControl.snp.bottom).offset(20)
        }
    }
    
    @objc func switchValueChanged(_ sender: UISwitch) {
        statusLabel.text = "Switch is \(sender.isOn ? "On" : "Off")"
        switchControl.accessibilityValue = sender.isOn ? "On" : "Off"
    }
}

Resources

Released under the MIT License.