带有间隔计时器的 SwiftUI 进度圈

问题描述

我正在尝试创建一个组件,其中我有多个时间间隔来控制圆形进度指示器。当一个间隔完成时,我想立即开始下一个间隔并开始下一个进度动画。

到目前为止,我唯一能做的就是从一个间隔结束到下一个间隔开始延迟 1 秒。

有人能指出我如何实现这一目标的方向吗?我对 Swift 和 SwiftUI 还很陌生,所以也许我在这里采取了完全错误方法,有更好的方法吗?

struct CircleProgress: View {
  let timer = Timer.publish(every: 1.0,on: .current,in: .common)
  
  let timeDurations = [1.0,2.0,3.0]

  @State var timeDuration = 0.0
  @State var durationIndex = 0
  @State var progress = 0.0
  @State var isFinished = false

  var body: some View {
    vstack {
      ZStack {
        Circle()
          .stroke(linewidth: 32)
          .opacity(0.25)
          .rotationEffect(.degrees(90))
          .padding()
        
        vstack {
          Text("Progress: \(progress)")
          if self.isFinished {
            Text("Finished")
          }
        }
        
        Circle()
          .trim(from: 0.0,to: CGFloat(min(progress,1.0)))
          .stroke(style: strokeStyle(linewidth: 32,lineCap: .round,lineJoin: .round))
          .foregroundColor(getstrokeColor())
          .rotationEffect(.degrees(-90))
          .padding()
          .onReceive(timer) { _ in
            if progress < 1 {
              withAnimation(Animation.linear(duration: 1.0)) {
                incrementProgress()
              }
            } else {
              progress = 0
              incrementDurationIndex()
            }
          }
      }.padding()
      Button(action: { startTimer() }) { Text("Start") }
      Spacer()
    }
  }
  
  func startTimer() {
    timeDuration = timeDurations[durationIndex]
    var _ = timer.connect()
  }
  
  func incrementDurationIndex() {
    durationIndex += 1
    if durationIndex < timeDurations.count {
      timeDuration = timeDurations[durationIndex]
    } else {
      setFinished()
      cancelTimer()
    }
  }
  
  func stopTimer() {
    timer.connect().cancel()
  }
  
  func setFinished() {
    isFinished = true
  }
  
  func incrementProgress() {
    progress += 1 / timeDuration
  }
  
  func cancelTimer() {
    timer.connect().cancel()
  }
  
  private func getstrokeColor() -> Color {
    ...
  }
}

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)