Таймер обратного отсчета расписания SwiftUI - пауза и запуск - PullRequest
0 голосов
/ 14 апреля 2020

Я пытаюсь настроить Clock (фактическое время) / Timer (CountDown) для моего приложения. Я знаю, что мое решение довольно грубое, но все работает нормально, НО. Когда я приостанавливаю обратный отсчет, а затем снова запускаю его - В первый раз Счетчик добавляет время (в течение примерно секунды), прошедшее с момента нажатия кнопки Пауза, и затем загружает мое значение timeCounter, которое я сохранил, и продолжает обратный отсчет. Почему? Также, если у вас есть более гладкое решение, я буду очень рад .. СПАСИБО!

    import SwiftUI

    struct Clock : View {

    @State private var nowDate: Date = Date()
    @State private var referenceDate: Date = Date()
    @State private var display: Bool = true

    @State private var updateTimer: Timer?

    @State private var timeCounter: Double = 0
    @State private var timerRunning: Bool = false

    var body: some View {
        VStack {
            Button(action: {
                self.display.toggle()
             }) {
                Text(display ? "COUNTDOWN" : "TIME")
            }

            Text(display ? "\(timeString(date: nowDate))" : "\(countDownString(for: referenceDate))")

            HStack {
                Button(action: {
                    self.display = false
                    self.timeCounter = 10
                    self.referenceDate = Date(timeIntervalSinceNow: self.timeCounter)
                }) {
                    Text("10")
                }
            }

            Button(action: {
                if self.timerRunning {
                    self.referenceDate = Date(timeIntervalSinceNow: self.timeCounter)
                    self.startTimer()
                    self.timerRunning.toggle()
                } else {
                    self.updateTimer?.invalidate()
                    self.timerRunning.toggle()
                }
            }) {
                Text(timerRunning ? "START" : "PAUSE")
            }
        }
        .onAppear {
            self.startTimer()
        }
    }

    //MARK: Timer
         func startTimer() {
        self.updateTimer = Timer.scheduledTimer(withTimeInterval: 1, repeats: true) { _ in
            self.nowDate = Date()
            if self.referenceDate.distance(to: self.nowDate) >= 0 {
                self.referenceDate = Date(timeIntervalSinceNow: 0)
                self.display = true
            }
            self.timeCounter -= 1
        }
    }

    //MARK: - CountDown Timer

    func countDownString(for date: Date) -> String {
        let calendar = Calendar(identifier: .gregorian)
        let components = calendar
            .dateComponents([.hour, .minute, .second],
                            from: nowDate,
                            to: referenceDate)
        return String(format: "%02d:%02d:%02d",
                      components.hour ?? 00,
                      components.minute ?? 00,
                      components.second ?? 00)
    }

    //MARK: - Clock Timer

    var timeFormat: DateFormatter {
        let formatter = DateFormatter()
        formatter.dateFormat = "HH:mm:ss"
        return formatter
    }

    func timeString(date: Date) -> String {
        let time = timeFormat.string(from: date)
        return time
    }
}
...