有没有更好的方法在剩余时间后从0.1-0.9修剪一个圆?

问题描述 投票:0回答:1

这是我当前的工作解决方案,但看起来很奇怪。我有点研究这些数字,直到它起作用,但我不完全理解数学。下面是我的代码。第二个圆圈

.trim
是我认为主要问题所在。

struct ContentView: View {
    
    @State private var timeRemaining: TimeInterval = 10
    @State private var startTime: Double = 10
    @State private var timer: Timer?
    @State private var isRunning: Bool = false
    
    var body: some View {
        
        ZStack {
            Circle()
                .trim(from: 0.1, to: 0.9)
                .stroke(style: StrokeStyle(lineWidth: 20, lineCap: .round, lineJoin: .round))
                .rotationEffect(.degrees(90))
                .opacity(0.3)
            
            Circle()
                .trim(from: 0.1, to: CGFloat((1.1 - (timeRemaining / (startTime) - 0.026)) / 1.25))
                .stroke(style: StrokeStyle(lineWidth: 20, lineCap: .round, lineJoin: .round))
                .rotationEffect(.degrees(90))
                .animation(.easeInOut(duration: 1))
            
            Text(formattedTime())
                .font(.largeTitle)
                .bold()
        }
        .frame(width: 250)
        
        Button {
            isRunning.toggle()
            if isRunning {
                startTimer()
            } else {
                stopTimer()
            }
        } label: {
            Image(systemName: isRunning ? "stop.fill" : "play.fill")
                .foregroundStyle(.foreground)
                .frame(width: 50, height: 50)
                .font(.largeTitle)
                .padding()
        }
    }
    
    private func startTimer() {
        timer = Timer.scheduledTimer(withTimeInterval: 1, repeats: true) { _ in
            if timeRemaining > 0 {
                timeRemaining -= 1
            } else {
                stopTimer()
            }
        }
    }
    
    private func stopTimer() {
        isRunning = false
        timer?.invalidate()
        timeRemaining = 10
        startTime = Double(timeRemaining)
    }
    
    private func formattedTime() -> String {
        let minutes = Int(timeRemaining) / 60
        let second = Int(timeRemaining) % 60
        return String(format: "%02d:%02d", minutes, second)
    }
}
animation swiftui timer geometry
1个回答
0
投票

您可以让动画在计时器倒计时的同时运行。它也需要

linear

为了使点在开始时可见,初始位置必须大于 0.1。 0.101 就可以了。

Circle()
    .trim(from: 0.1, to: isRunning ? 0.9 : 0.101)
    .stroke(style: StrokeStyle(lineWidth: 20, lineCap: .round, lineJoin: .round))
    .rotationEffect(.degrees(90))
    .animation(.linear(duration: isRunning ? 10 : 0), value: isRunning)

Animation

© www.soinside.com 2019 - 2024. All rights reserved.