Skip to content

Instantly share code, notes, and snippets.

@badrinathvm
Last active June 16, 2024 21:40
Show Gist options
  • Save badrinathvm/38b1f967e42a9b99d077398406c6e5f0 to your computer and use it in GitHub Desktop.
Save badrinathvm/38b1f967e42a9b99d077398406c6e5f0 to your computer and use it in GitHub Desktop.
Circular Loader View
import Combine
import Foundation
import SwiftUI
struct CircularLoaderView: View {
@State private var circleProgress: CGFloat = 0.0
@State private var timerCancellable: Cancellable? = nil
@State private var isComplete = false
let gradient = AngularGradient(
gradient: Gradient(colors: [.green, .blue, .yellow]),
center: .center
)
var body: some View {
VStack {
ZStack {
Circle()
.trim(from: 0, to: isComplete ? 1.0 : circleProgress)
.stroke(gradient, style: StrokeStyle(lineWidth: 10, lineCap: .round))
.rotationEffect(.degrees(-90))
.animation(.easeInOut(duration: 2.0), value: circleProgress)
.opacity(isComplete ? 0 : 1)
Circle()
.fill(gradient)
.opacity(isComplete ? 1 : 0)
.overlay(
Image(systemName: "checkmark")
.resizable()
.renderingMode(.template)
.foregroundColor(Color.white)
.frame(width: 24, height: 24)
.font(Font.system(size: 24, weight: .bold))
)
}
.frame(height: 100)
}
.onAppear {
startTimer()
}
.onDisappear {
stopTimer()
}
}
private func startTimer() {
let timerPublisher = Timer.publish(every: 0.5, on: .main, in: .common).autoconnect()
timerCancellable = timerPublisher.sink { _ in
// place to make the network call
if circleProgress < 1.0 {
circleProgress += 0.05
} else {
print("Stop the Timer")
stopTimer()
self.isComplete = true
}
}
}
private func stopTimer() {
timerCancellable?.cancel()
timerCancellable = nil
}
}
#Preview {
VStack{
CircularLoaderView()
}
}
Usign Switch case approach
struct CircularLoaderView: View {
@State private var circleProgress: CGFloat = 0.0
@State private var timerCancellable: Cancellable? = nil
@State private var isComplete = false
let gradient = AngularGradient(
gradient: Gradient(colors: [.green, .blue, .yellow]),
center: .center
)
var body: some View {
VStack {
ZStack {
switch isComplete {
case false:
Circle()
.trim(from: 0, to: isComplete ? 1.0 : circleProgress)
.stroke(gradient, style: StrokeStyle(lineWidth: 10, lineCap: .round))
.rotationEffect(.degrees(-90))
.animation(.easeInOut(duration: 2.0), value: circleProgress)
// .opacity(isComplete ? 0 : 1)
case true:
Circle()
.fill(gradient)
// .opacity(isComplete ? 1 : 0)
.overlay(
Image(systemName: "checkmark")
.resizable()
.renderingMode(.template)
.foregroundColor(Color.white)
.frame(width: 24, height: 24)
.font(Font.system(size: 24, weight: .bold))
)
}
}
.frame(height: 100)
}
.onAppear {
startTimer()
}
.onDisappear {
stopTimer()
}
}
private func startTimer() {
let timerPublisher = Timer.publish(every: 0.5, on: .main, in: .common).autoconnect()
timerCancellable = timerPublisher.sink { _ in
// place to make the network call
if circleProgress < 1.0 {
circleProgress += 0.05
} else {
print("Stop the Timer")
stopTimer()
self.isComplete = true
}
}
}
private func stopTimer() {
timerCancellable?.cancel()
timerCancellable = nil
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment