Home > OS >  Circle().trim not updating when a variable updates
Circle().trim not updating when a variable updates

Time:10-06

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)
    }
}

Image of ContentView.swift.

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
  • Related