SwiftUI - 如何使用剩余时间制作倒计时器

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

我想实现一个基于当前时间和结束时间的倒计时器。

例如:

  • 当前时间:20:30:30

  • 结束时间始终是:23:59:59

    -> 我将实现一个倒计时器:03:29:29

我下面的代码就是这样做的,但我觉得它不是很漂亮。我希望我的结束时间是动态的,而不是硬性规定的数字:23、59、59。

以下是我的全部代码

struct TimerView: View {
    @State var timeRemaining = Calendar(identifier: .gregorian).dateComponents(in: .current, from: Date())
    let timer = Timer.publish(every: 1, on: .main, in: .common).autoconnect()
    var body: some View {
        HStack(spacing: 12) {
            timerStringView(timer: hourString(date: timeRemaining))
            timerStringView(timer: minuteString(date: timeRemaining) )
            timerStringView(timer: secondString(date: timeRemaining))
        }
        .frame(width: 300, height: 34)
        .background(Color.gray)
        .onReceive(timer) { _ in
            timeRemaining = Calendar(identifier: .gregorian).dateComponents(in: .current, from: Date())
        }
    }
    
    func timerStringView(timer: String) -> some View {
        Text(timer)
            .font(.system(size: 18, weight: .bold))
            .foregroundColor(.black)
            .background(Color.white)
            .cornerRadius(6)
    }
    
    func hourString(date: DateComponents) -> String {
        return String(format: "%02i", 23 - (date.hour ?? 00))
    }
    
    func minuteString(date: DateComponents) -> String {
        return String(format: "%02i", 59 - (date.minute ?? 00))
    }
    
    func secondString(date: DateComponents) -> String {
        return String(format: "%02i", 59 - (date.second ?? 00))
    }
}
swift swiftui countdown countdowntimer
1个回答
0
投票

更好的方法是使用

DateComponents
进行日期数学计算,有一个 API
dateComponents(_:from:to:)
,其中
from
to
也可以是
DateComponents

struct TimerView: View {
    @State private var differenceComponents = DateComponents()       
    private var endDateComponents = DateComponents(hour:23, minute: 59, second: 59)

    private let timer = Timer.publish(every: 1, on: .main, in: .common).autoconnect()
    private let calendar = Calendar(identifier: .gregorian)
    
    var body: some View {
        HStack(spacing: 12) {
            timerStringView(value: differenceComponents.hour ?? 0)
            timerStringView(value: differenceComponents.minute ?? 0 )
            timerStringView(value: differenceComponents.second ?? 0)
        }
        .frame(width: 300, height: 34)
        .background(Color.gray)
        .onReceive(timer) { _ in
            let nowComponents = calendar.dateComponents([.hour, .minute, .second], from: .now)
            differenceComponents = calendar.dateComponents([.hour, .minute, .second], from: nowComponents, to: endDateComponents)
        }
    }
    
    func timerStringView(value: Int) -> some View {
        Text(String(format: "%02d", value))
            .font(.system(size: 18, weight: .bold))
            .foregroundColor(.black)
            .background(Color.white)
            .cornerRadius(6)
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.