Last active
June 16, 2024 21:40
-
-
Save badrinathvm/38b1f967e42a9b99d077398406c6e5f0 to your computer and use it in GitHub Desktop.
Circular Loader View
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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