Skip to content

Instantly share code, notes, and snippets.

@Inncoder
Created November 18, 2020 23:17
Show Gist options
  • Save Inncoder/f0bfbcfdb0e237947aa6d758cd6f1cc8 to your computer and use it in GitHub Desktop.
Save Inncoder/f0bfbcfdb0e237947aa6d758cd6f1cc8 to your computer and use it in GitHub Desktop.
darkmode toggle
//
// Toggle.swift
// Animations
//
// Created by Inncoder on 18/11/2020.
// Copyright © 2020 Inncoder AS. All rights reserved.
//
import SwiftUI
struct Toggle: View {
@State private var isDarkmode = false
@State private var toggled = false
@State private var animating = false
@State private var scale: CGFloat = 1
@State private var circleColor: Color = Color.white
@State private var ringColor: Color = Color(UIColor.darkGray)
@State private var backgroundSize: CGFloat = 0
var body: some View {
ZStack {
ZStack { Rectangle() }
.foregroundColor(isDarkmode ? darkmodeColor : .white)
.edgesIgnoringSafeArea(.all)
Circle()
.frame(width: backgroundSize, height: backgroundSize)
.offset(x: toggled ? toggleSize / 4 : -(toggleSize / 4))
.foregroundColor(toggled ? darkmodeColor : .white)
Capsule()
.frame(width: toggleSize, height: toggleSize / 2)
.foregroundColor(.gray)
ZStack {
Circle()
.stroke(lineWidth: 10)
.foregroundColor(ringColor)
Circle()
.foregroundColor(circleColor)
}
.scaleEffect(scale)
.offset(x: toggled ? toggleSize / 4 : -(toggleSize / 4))
.frame(width: (toggleSize / 2) - (toggleSize * 0.1), height: (toggleSize / 2) - (toggleSize * 0.1))
.onTapGesture {
if !animating {
animating = true
withAnimation(Animation.easeInOut(duration: toggleTime)) {
toggled.toggle()
}
withAnimation(Animation.easeIn(duration: (toggleTime / 2) + (toggleTime / 4))) {
scale = 2
if toggled {
circleColor = darkmodeColor
ringColor = Color(UIColor.lightGray)
} else {
circleColor = .white
ringColor = Color(UIColor.darkGray)
}
}
DispatchQueue.main.asyncAfter(deadline: .now() + (toggleTime / 2) + (toggleTime / 4)) {
withAnimation(Animation.easeOut(duration: toggleTime / 4)) {
scale = 1
}
}
DispatchQueue.main.asyncAfter(deadline: .now() + toggleTime) {
withAnimation(Animation.easeOut(duration: toggleTime)) {
backgroundSize = UIScreen.main.bounds.height * 1.1
}
DispatchQueue.main.asyncAfter(deadline: .now() + toggleTime) {
isDarkmode.toggle()
backgroundSize = (toggleSize / 2) - (toggleSize * 0.075)
animating = false
}
}
}
}
}
.onAppear {
backgroundSize = (toggleSize / 2) - (toggleSize * 0.075)
}
.preferredColorScheme(isDarkmode ? .dark : .light)
}
//MARK: - Drawing constants
let toggleSize: CGFloat = 150
let toggleTime: Double = 0.75
let darkmodeColor: Color = Color(red: 0.189, green: 0.187, blue: 0.256)
}
struct Toggle_Previews: PreviewProvider {
static var previews: some View {
Toggle()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment