Swift
iOS Development
Radio Buttons
Checkboxes
SwiftUI

How to create radio buttons and checkbox in swift iOS?

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

UIKit does not ship with native radio button or checkbox controls, so in iOS you usually build them from buttons, images, or list selections. SwiftUI has a built-in Toggle for checkbox-like behavior, but it still does not provide a true radio button control. The right implementation depends on whether you are using UIKit or SwiftUI and whether the selection should be single-choice or multi-choice.

Checkbox Behavior in UIKit

A checkbox is just a control with two states: selected and unselected. In UIKit, a UIButton works well for this.

swift
1import UIKit
2
3final class CheckboxViewController: UIViewController {
4    private let checkbox = UIButton(type: .system)
5
6    override func viewDidLoad() {
7        super.viewDidLoad()
8
9        checkbox.setTitle(" Receive newsletter", for: .normal)
10        checkbox.setImage(UIImage(systemName: "square"), for: .normal)
11        checkbox.setImage(UIImage(systemName: "checkmark.square.fill"), for: .selected)
12        checkbox.tintColor = .systemBlue
13        checkbox.addTarget(self, action: #selector(toggleCheckbox), for: .touchUpInside)
14
15        checkbox.translatesAutoresizingMaskIntoConstraints = false
16        view.addSubview(checkbox)
17        NSLayoutConstraint.activate([
18            checkbox.centerXAnchor.constraint(equalTo: view.centerXAnchor),
19            checkbox.centerYAnchor.constraint(equalTo: view.centerYAnchor)
20        ])
21    }
22
23    @objc private func toggleCheckbox() {
24        checkbox.isSelected.toggle()
25    }
26}

This gives you a simple reusable checkbox with visible state changes.

Radio Button Behavior in UIKit

A radio button is different because only one item in the group can be selected at a time. The easiest approach is still UIButton, but now you manage the selection group yourself.

swift
1import UIKit
2
3final class RadioGroupViewController: UIViewController {
4    private var buttons: [UIButton] = []
5    private let titles = ["Small", "Medium", "Large"]
6
7    override func viewDidLoad() {
8        super.viewDidLoad()
9
10        let stack = UIStackView()
11        stack.axis = .vertical
12        stack.spacing = 12
13        stack.translatesAutoresizingMaskIntoConstraints = false
14        view.addSubview(stack)
15
16        NSLayoutConstraint.activate([
17            stack.centerXAnchor.constraint(equalTo: view.centerXAnchor),
18            stack.centerYAnchor.constraint(equalTo: view.centerYAnchor)
19        ])
20
21        for title in titles {
22            let button = UIButton(type: .system)
23            button.setTitle(" \(title)", for: .normal)
24            button.setImage(UIImage(systemName: "circle"), for: .normal)
25            button.setImage(UIImage(systemName: "largecircle.fill.circle"), for: .selected)
26            button.contentHorizontalAlignment = .left
27            button.addTarget(self, action: #selector(selectRadioButton(_:)), for: .touchUpInside)
28            buttons.append(button)
29            stack.addArrangedSubview(button)
30        }
31    }
32
33    @objc private func selectRadioButton(_ sender: UIButton) {
34        for button in buttons {
35            button.isSelected = (button === sender)
36        }
37    }
38}

This enforces the single-selection rule that defines radio buttons.

SwiftUI Equivalents

In SwiftUI, a checkbox-like control is usually a Toggle.

swift
1import SwiftUI
2
3struct SettingsView: View {
4    @State private var receiveNewsletter = false
5
6    var body: some View {
7        Toggle("Receive newsletter", isOn: $receiveNewsletter)
8            .padding()
9    }
10}

For radio-button style selection, a Picker with a suitable style is usually more idiomatic than building literal radio circles by hand.

swift
1import SwiftUI
2
3struct SizePickerView: View {
4    @State private var size = "Medium"
5    let sizes = ["Small", "Medium", "Large"]
6
7    var body: some View {
8        Picker("Size", selection: $size) {
9            ForEach(sizes, id: \.self) { size in
10                Text(size).tag(size)
11            }
12        }
13        .pickerStyle(.segmented)
14        .padding()
15    }
16}

Accessibility and State Ownership

Whichever framework you use, keep the selection state in one clear place and expose it accessibly. For UIKit, set accessibility labels and values. For SwiftUI, choose controls that already integrate well with the system.

A hand-drawn circle that looks like a radio button is not enough if it does not behave like a real control for assistive technologies.

Common Pitfalls

The most common mistake is assuming UIKit has built-in radio button and checkbox controls. It does not.

Another issue is implementing radio buttons without a central selection rule, which allows multiple buttons in the same group to stay selected.

Developers also often focus only on visuals and forget accessibility and actual control state.

Finally, in SwiftUI, forcing a UIKit-style radio button look is often less useful than using Toggle or Picker, which already match platform conventions better.

Summary

  • UIKit does not provide built-in radio button or checkbox controls.
  • Use a UIButton with selected and unselected images for checkboxes.
  • Use a button group with exclusive selection logic for radio buttons.
  • In SwiftUI, use Toggle for checkbox-like behavior and Picker for single selection.
  • Keep selection state explicit and make the control accessible, not only visually similar.

Course illustration
Course illustration

All Rights Reserved.