Skip to content

A custom Toggle View constructed in SwiftUI

License

Notifications You must be signed in to change notification settings

pianometal/ToggleView

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

7 Commits
 
 
 
 
 
 
 
 

Repository files navigation

ToggleView

Requirements

  • 📲 iOS 16
  • 🔨 Xcode 15

Features

  • Resizeable and scalable
  • Support for Dark Mode
  • Labels displaying the state
  • Customize the following
    • Size
    • Colors
    • Font design
    • Animation
    • On and Off labels

Screenshots

Toggle View Light Mode Toggle View Dark Mode

Video

toggleVideo.mov

Code

Add this snippet to your project

//
//  ToggleView.swift
//
//  Created by Kyle Lovely
//
//  https://github.com/pianometal
//

import SwiftUI

/// Custom `.switch` style `Toggle` that scales appropriately based on ``height``
struct ToggleView: View {
    
    @Environment(\.colorScheme) private var colorScheme
    
    @Binding var isOn: Bool
    
    var height: CGFloat = 32
    var color: Color = .blue
    var fontDesign: Font.Design = .monospaced
    var animation = Animation.spring(response: 0.2, dampingFraction: 0.5, blendDuration: 0.75)
    
    var on = "ON"
    var off = "OFF"
    
    var body: some View {
        
        HStack {
            
            if isOn { Spacer() }
            
            ZStack {
                
                Circle()
                    .fill(colorScheme == .light ? .white : .black)
                    .padding(padding)
                
                Text(isOn ? on : off)
                    .font(.system(size: fontSize, weight: .black, design: fontDesign))
                    .foregroundStyle(onColor.gradient)
            }
            
            if !isOn { Spacer() }
        }
        .frame(width: width, height: height)
        .background(onColor.gradient)
        .clipShape(Capsule())
        .onTapGesture { toggle() }
    }
    
    private func toggle() {
        withAnimation(animation) { isOn.toggle() }
    }
    
    private var width: CGFloat { height * 1.75 }
    private var padding: CGFloat { height / 16 }
    private var fontSize: CGFloat { height * 0.375 }
    private var onColor: Color { isOn ? color : .gray }
}

#Preview {
    ToggleView(isOn: .constant(true))
}