Swift UI - progress bar в минута: секундах как преобразовать в формат CGFloat

Подскажите новичку пожалуйста как преобразовать или связать минуты:секунды в формат CGFloat?

Хочу сделать заполнение шкалы по таймеру к примеру нажал кнопку, пошел таймер, а прогресс бар соответсвенно заполняется указанным минутам секундам. Пример моего кода для понимания что я хочу (реализовал с помощью CGFloat т.к. trim поддерживает CGFloat).

@State var circleProgress: CGFloat = 0.0

 Circle()
     .trim(from: 0.0, to: circleProgress)
     .stroke(Color.red, lineWidth: 10)
     .frame(width: 160, height: 190)
     .rotationEffect(Angle(degrees: -90))

Ответы (1 шт):

Автор решения: schmidt9

Вот пример таймера с обратным отсчетом 10 секунд

struct ContentView: View {

    @State var timerStarted = false

    var body: some View {

        VStack {
            Button(action: { self.timerStarted = true },
                   label: { Text("Start timer") })

            CircleView(timerStarted: $timerStarted)
                .frame(width: 200, height: 200, alignment: .center)
        }

    }

}

Отдельный класс для кругового вью с отображением оставшегося времени в центре

import SwiftUI
import Combine

struct CircleView : View {

    private let totalSeconds: CGFloat = 10.0
    private let timer = Timer.publish(every: 1, on: .main, in: .common).autoconnect()

    @State private var timeRemaining = 10
    @State private var circleProgress: CGFloat = 0.0

    @Binding var timerStarted: Bool

    private var formattedTime: String {
        let formatter = DateFormatter()
        formatter.dateFormat = "mm:ss"
        return formatter.string(from: Date(timeIntervalSince1970: Double(timeRemaining)))
    }

    var body: some View {
        ZStack {
            Circle()
                .trim(from: 0.0, to: circleProgress)
                .stroke(Color.red, lineWidth: 10)
                .rotationEffect(Angle(degrees: -90))
                .padding(EdgeInsets(top: 5, leading: 5, bottom: 5, trailing: 5))
                .onReceive(timer) {_ in
                    self.onTimerReceive(self.timer)
            }

            Text(formattedTime)
        }
    }

    func onTimerReceive<T: Publisher>(_ timer: T) {
        if self.timerStarted {
            if self.timeRemaining == 0 {
                self.timer.upstream.connect().cancel()
                return
            }

            self.timeRemaining -= 1

            let step: CGFloat = 1.0 / self.totalSeconds
            self.circleProgress += step
        }
    }

}
→ Ссылка