Skip to content

Instantly share code, notes, and snippets.

@fxm90
Last active March 31, 2023 17:38
Show Gist options
  • Save fxm90/b56d537d9fb8bf20d573a45367e18c4f to your computer and use it in GitHub Desktop.
Save fxm90/b56d537d9fb8bf20d573a45367e18c4f to your computer and use it in GitHub Desktop.
A fully configurable toggle style for SwiftUI, making the Toggle look like a checkbox.
//
// CheckboxToggleStyle.swift
//
// Created by Felix Mau on 25.05.2021.
// Copyright © 2021 Felix Mau. All rights reserved.
//
/// A fully configurable toggle style for SwiftUI, making the Toggle look like a checkbox.
struct CheckboxToggleStyle: ToggleStyle {
// MARK: - Config
private enum Config {
static let iconSize: CGFloat = 22
static let animationDuration: TimeInterval = 0.15
static let onIconName = "checkmark.circle"
static let offIconName = "circle"
}
// MARK: - Public properties
var onColor: Color = .blue
var offColor: Color = .gray
// MARK: - Public methods
func makeBody(configuration: Configuration) -> some View {
HStack {
configuration.label
Spacer()
ZStack {
Image(systemName: Config.offIconName)
.resizable()
.foregroundColor(offColor)
Image(systemName: Config.onIconName)
.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