Skip to content

Instantly share code, notes, and snippets.

@mattyoung
Created December 31, 2022 20:50
Show Gist options
  • Save mattyoung/c456c5c79ae68d482e8b837889719da7 to your computer and use it in GitHub Desktop.
Save mattyoung/c456c5c79ae68d482e8b837889719da7 to your computer and use it in GitHub Desktop.
//
// LikeView.swift
// lottie-first
//
// Created by Matthew Young on 12/31/22.
//
import SwiftUI
import Lottie
typealias ProgressAnimationRange = (from: AnimationProgressTime, to: AnimationProgressTime)
typealias ProgressAnimationParameters = (on: ProgressAnimationRange, off: ProgressAnimationRange)
struct LottieToggleAnimation {
let fileName: String
let progressAnimationParameters: ProgressAnimationParameters
static let like = LottieToggleAnimation(fileName: "like",
progressAnimationParameters: (on: (from: 0, to: 0.5), off: (from: 0.5, to: 1)))
static let sunmoon = LottieToggleAnimation(fileName: "sunmoon-toggle-switch",
progressAnimationParameters: (on: (from: 10 / 28, to: 1), off: (from: 0, to: 10 / 28)))
static let dayAndNight = LottieToggleAnimation(fileName: "day-and-night-mode-toggle-switch",
progressAnimationParameters: (on: (from: 0, to: 0.5), off: (from: 0.5, to: 1)))
}
struct LottieToggleView: UIViewRepresentable {
let isOn: Bool
let lottieToggleAnimation: LottieToggleAnimation
init(isOn: Bool, lottieToggleAnimation: LottieToggleAnimation) {
self.isOn = isOn
self.lottieToggleAnimation = lottieToggleAnimation
}
func makeUIView(context: Context) -> LottieAnimationView {
let animationView = LottieAnimationView(animation: LottieAnimation.named(lottieToggleAnimation.fileName))
animationView.contentMode = .scaleAspectFit
animationView.animationSpeed = 2
return animationView
}
func updateUIView(_ animationView: UIViewType, context: Context) {
if isOn {
animationView.play(fromProgress: lottieToggleAnimation.progressAnimationParameters.on.from, toProgress: lottieToggleAnimation.progressAnimationParameters.on.to, loopMode: .playOnce, completion: nil)
} else {
animationView.play(fromProgress: lottieToggleAnimation.progressAnimationParameters.off.from, toProgress: lottieToggleAnimation.progressAnimationParameters.off.to, loopMode: .playOnce, completion: nil)
}
}
}
struct LottieToggleStyle: ToggleStyle {
let lottieToggleAnimation: LottieToggleAnimation
init(lottieToggleAnimation: LottieToggleAnimation) {
self.lottieToggleAnimation = lottieToggleAnimation
}
func makeBody(configuration: Configuration) -> some View {
Color.clear
.overlay {
LottieToggleView(isOn: configuration.isOn, lottieToggleAnimation: lottieToggleAnimation)
}
.onTapGesture {
configuration.isOn.toggle()
}
}
}
struct LottieToggleDemo: View {
@State private var isOn = false
var body: some View {
VStack {
Text(String(describing: isOn))
.font(.largeTitle)
Toggle("On/Off", isOn: $isOn)
}
}
}
struct LikeViewPreviewHelper: View {
var body: some View {
VStack {
LottieToggleDemo()
.toggleStyle(LottieToggleStyle(lottieToggleAnimation: LottieToggleAnimation.sunmoon))
LottieToggleDemo()
.toggleStyle(LottieToggleStyle(lottieToggleAnimation: LottieToggleAnimation.like))
LottieToggleDemo()
.toggleStyle(LottieToggleStyle(lottieToggleAnimation: LottieToggleAnimation.dayAndNight))
}
}
}
struct LikeView_Previews: PreviewProvider {
static var previews: some View {
LikeViewPreviewHelper()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment