iOS
UISwitch
Swift programming
iOS development
Xcode

iOS - How to set a UISwitch programmatically

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

Introduction

Creating a UISwitch in code is straightforward once you separate three concerns: creating the control, placing it on screen, and reacting when its value changes. Programmatic setup is especially useful when your UI is built dynamically, reused in custom views, or configured differently for each device state.

Create and Configure the Switch

In UIKit, UISwitch is a normal view object. You can instantiate it, set its initial state, and customize a few appearance properties before adding it to the view hierarchy.

swift
1import UIKit
2
3final class SettingsViewController: UIViewController {
4    private let wifiSwitch = UISwitch()
5
6    override func viewDidLoad() {
7        super.viewDidLoad()
8        view.backgroundColor = .systemBackground
9
10        wifiSwitch.translatesAutoresizingMaskIntoConstraints = false
11        wifiSwitch.setOn(true, animated: false)
12        wifiSwitch.onTintColor = .systemGreen
13        wifiSwitch.thumbTintColor = .white
14
15        view.addSubview(wifiSwitch)
16
17        NSLayoutConstraint.activate([
18            wifiSwitch.centerXAnchor.constraint(equalTo: view.centerXAnchor),
19            wifiSwitch.centerYAnchor.constraint(equalTo: view.centerYAnchor)
20        ])
21    }
22}

Two details are worth noticing. First, setOn(_:animated:) is the clearest way to set the switch programmatically. Second, UISwitch has an intrinsic content size, so you usually position it with Auto Layout rather than trying to force a custom width and height.

React to User Changes

Setting the value is only half the job. Most screens also need to respond when the user toggles the control. In UIKit, the normal event for that is .valueChanged.

swift
1import UIKit
2
3final class NotificationsViewController: UIViewController {
4    private let notificationsSwitch = UISwitch()
5
6    override func viewDidLoad() {
7        super.viewDidLoad()
8        view.backgroundColor = .systemBackground
9
10        notificationsSwitch.translatesAutoresizingMaskIntoConstraints = false
11        notificationsSwitch.isOn = false
12        notificationsSwitch.addTarget(
13            self,
14            action: #selector(didToggleNotifications(_:)),
15            for: .valueChanged
16        )
17
18        view.addSubview(notificationsSwitch)
19
20        NSLayoutConstraint.activate([
21            notificationsSwitch.centerXAnchor.constraint(equalTo: view.centerXAnchor),
22            notificationsSwitch.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 40)
23        ])
24    }
25
26    @objc private func didToggleNotifications(_ sender: UISwitch) {
27        if sender.isOn {
28            print("Notifications enabled")
29        } else {
30            print("Notifications disabled")
31        }
32    }
33}

You can read the current value from sender.isOn. That property is also the simplest way to inspect the state elsewhere in your code.

Update the Switch from Application State

Programmatic control becomes more useful when the switch reflects a saved preference or service status. A common pattern is to load the initial value from UserDefaults and write it back whenever the user changes the switch.

swift
1import UIKit
2
3final class PreferenceViewController: UIViewController {
4    private let darkModeSwitch = UISwitch()
5    private let key = "dark_mode_enabled"
6
7    override func viewDidLoad() {
8        super.viewDidLoad()
9        view.backgroundColor = .systemBackground
10
11        darkModeSwitch.translatesAutoresizingMaskIntoConstraints = false
12        darkModeSwitch.isOn = UserDefaults.standard.bool(forKey: key)
13        darkModeSwitch.addTarget(self, action: #selector(toggleChanged(_:)), for: .valueChanged)
14
15        view.addSubview(darkModeSwitch)
16
17        NSLayoutConstraint.activate([
18            darkModeSwitch.centerXAnchor.constraint(equalTo: view.centerXAnchor),
19            darkModeSwitch.centerYAnchor.constraint(equalTo: view.centerYAnchor)
20        ])
21    }
22
23    @objc private func toggleChanged(_ sender: UISwitch) {
24        UserDefaults.standard.set(sender.isOn, forKey: key)
25    }
26}

This pattern keeps the UI and stored settings in sync. It is also easy to test because the switch state is just a Boolean value flowing into normal application code.

When to Use isOn Versus setOn

Both isOn and setOn(_:animated:) can change the state. Use isOn for a plain assignment when animation does not matter, and use setOn(_:animated:) when you want the user to see the state transition. For example, if a network callback enables a feature after the screen is already visible, the animated version often feels more natural.

Also remember that changing the switch programmatically does not automatically trigger your .valueChanged handler. If your app depends on shared logic, call that logic directly after updating the state instead of assuming the control event will fire for you.

Common Pitfalls

One common mistake is trying to size the switch manually with a frame and expecting it to stretch like a generic view. UISwitch renders at a system-defined size, so scaling it with layout constraints usually leads to odd results. Position it; do not fight its intrinsic size.

Another mistake is forgetting to set translatesAutoresizingMaskIntoConstraints to false before adding Auto Layout constraints. If you omit that, UIKit may create conflicting constraints and the switch can end up misplaced.

Developers also often set the initial value in viewDidLoad but forget to refresh it later when external state changes. If the switch reflects server state, permissions, or persisted settings, update it again when that state changes.

Finally, do not confuse disabling a switch with turning it off. isEnabled = false prevents interaction, while isOn = false changes the actual Boolean value.

Summary

  • Create a UISwitch with normal UIKit code and add it to the view hierarchy.
  • Use setOn(_:animated:) or isOn to control the state programmatically.
  • Attach a .valueChanged target to react when the user toggles the switch.
  • Use Auto Layout for placement because UISwitch already has an intrinsic size.
  • Keep stored settings and UI state synchronized instead of treating the switch as the source of truth.

Related reading
Free course
Beginner
7 lessons
2 hours
Tackling System Design Interview Problems

A short course that equips you with the skills to approach system design interviews methodically.

Start the free course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

All Rights Reserved.