I'm trying to make a timer style app where the circle will diminish while the time decreases, by using the circle circle().trim
function. The value is being passed through as a variable into another script, which handles the trimming of the circle. I've tried to put the direct formula to find the percentage instead of a variable, though that did not help either. Any help is greatly appreciated.
E.g. the timer starts at 60, when it gets down to 15 there should only be 25% of the circle left.
ContentView.swift
struct ContentView: View {
@State var countdownTimer: Int = 60
@State var timerCounting: Bool = true
let timer = Timer.publish(every: 1, on: .main, in: .common).autoconnect()
@State var timerMax: Int = 60
var body: some View {
let completionRing = Double(countdownTimer) / Double(timerMax)
VStack {
Text("\(completionRing) is")
ZStack {
ProgressRing(ringPercentage: completionRing)
.frame(width: 300, height: 300)
Text("\(countdownTimer)")
.onReceive(timer) { _ in
if countdownTimer > 0 && timerCounting {
countdownTimer -= 1
} else {
timerCounting = false
}
}
.font(.system(size: 80))
}
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
ProgressRing.swift
import SwiftUI
struct ProgressRing: View {
@State var ringPercentage: Double
var body: some View {
VStack {
ZStack {
Circle()
.stroke(
Color.green.opacity(0.5),
lineWidth: 15
)
Circle()
.trim(from: 0, to: ringPercentage)
.stroke(
Color.green,
style: StrokeStyle (
lineWidth: 15,
lineCap: .round
)
)
.rotationEffect(.degrees(-90))
.animation(.easeOut, value: ringPercentage)
}
}
}
}
struct ProgressRing_Previews: PreviewProvider {
static var previews: some View {
ProgressRing(ringPercentage: 1)
}
}
CodePudding user response:
@State
is for local mutable state within a View
. In this case, you don't want to store/mutate ringPercentage
within ProgressRing
, so it should just be a parameter (without @State
):
struct ProgressRing: View {
var ringPercentage: Double