Skip to content

Instantly share code, notes, and snippets.

@fxm90
Last active January 25, 2026 15:57
Show Gist options
  • Select an option

  • Save fxm90/b56d537d9fb8bf20d573a45367e18c4f to your computer and use it in GitHub Desktop.

Select an option

Save fxm90/b56d537d9fb8bf20d573a45367e18c4f to your computer and use it in GitHub Desktop.
A custom `ToggleStyle` that presents a SwiftUI `Toggle` as a checkbox.
//
// CheckboxToggleStyle.swift
//
// Created by Felix Mau on 25.05.2021.
// Copyright © 2021 Felix Mau. All rights reserved.
//
import SwiftUI
// MARK: - Config
private enum Config {
static let iconSize: CGFloat = 22
static let animationDuration: TimeInterval = 0.15
enum SystemImageName {
static let on = "checkmark.circle"
static let off = "circle"
}
}
/// A custom `ToggleStyle` that presents a SwiftUI `Toggle` as a checkbox.
struct CheckboxToggleStyle: ToggleStyle {
// MARK: - Public Properties
let onColor: Color
let offColor: Color
// MARK: - Initializer
init(onColor: Color = .blue, offColor: Color = .gray) {
self.onColor = onColor
self.offColor = offColor
}
// MARK: - Public Methods
func makeBody(configuration: Configuration) -> some View {
HStack {
configuration.label
Spacer()
ZStack {
Image(systemName: Config.SystemImageName.off)
.resizable()
.foregroundColor(offColor)
Image(systemName: Config.SystemImageName.on)
.resizable()
.foregroundColor(onColor)
// Toggling opacity is the easiest way to animate
// the image transition.
.opacity(configuration.isOn ? 1 : 0)
}
.frame(width: Config.iconSize, height: Config.iconSize)
.animation(.easeInOut(duration: Config.animationDuration))
}
.onTapGesture {
configuration.isOn.toggle()
}
}
}
@fxm90
Copy link
Author

fxm90 commented May 25, 2021

Example Code

struct ContentView: View {

  // MARK: - Private Properties

  @State
  private var isOriginalToggleOn = false

  @State
  private var isCustomToggleOn = false

  // MARK: - Render

  var body: some View {
    List {
      Section(header: Text("Checkbox Toggle Style")) {
        Toggle("Original Toggle", isOn: $isOriginalToggleOn)

        Toggle("Custom Toggle", isOn: $isCustomToggleOn)
          .toggleStyle(CheckboxToggleStyle())
      }
    }
    .listStyle(InsetGroupedListStyle())
  }
}

The code above will produce the following result.

Dark-Mode / Off-State Light-Mode / On-State
CheckboxToggle--Dark--Off CheckboxToggle

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment