繁体   English   中英

如何使用 SwiftUI 中的日期制作循环计时器?

[英]How to make a circular timer with Dates in SwiftUI?

我需要一些帮助。 我想出了如何制作一个循环计时器,但不是那样,我想用日期制作它,我的例子是使用 Int 值。 例如,我正在尝试从未来日期(例如:2 月 4 日 11:00 PM)到日期(2 月 4 日 9:00 PM)倒计时。

这是我写的代码:

import SwiftUI
 
let timer = Timer
    .publish(every: 1, on: .main, in: .common)
    .autoconnect()

struct CircularTimer: View {
    @State var counter: Int = 0
    var countTo: Int = 120
    var nowDate = Date()
    var futureDate = Date.distantFuture
    var body: some View {
        VStack{
            ZStack{
                Circle()
                    .fill(Color.clear)
                    .frame(width: 250, height: 250)
                    .overlay(
                        Circle().stroke(Color.green, lineWidth: 25)
                )
                 
                Circle()
                    .fill(Color.clear)
                    .frame(width: 250, height: 250)
                    .overlay(
                        Circle().trim(from:0, to: progress())
                            .stroke(
                                style: StrokeStyle(
                                    lineWidth: 25,
                                    lineCap: .round,
                                    lineJoin:.round
                                )
                            )
                            .foregroundColor(
                                (completed() ? Color.orange : Color.red)
                            ).animation(
                                .easeInOut(duration: 0.2)
                            )
                    )
            }
        }.onReceive(timer) { time in
            if (self.counter < self.countTo) {
                self.counter += 1
            }
                
        }
    }
    func completed() -> Bool {
        return progress() == 1
    }
     
    func progress() -> CGFloat {
        return (CGFloat(counter) / CGFloat(countTo))
    }
}

我也是 SwiftUI 编程的新手,但我尝试重写您的解决方案以获得所需的 output。 您只需要使用DateComponents ,然后使用TimeInterval ,因为这两个允许您在几秒钟内表示Date()变量,因此您可以轻松地将它用于您的计时器。 这里是:

import SwiftUI
 
let timer = Timer
    .publish(every: 1, on: .main, in: .common)
    .autoconnect()

struct CircularTimer: View {
    // MARK: Changed type to TIMEINTERVAL
    @State var counter: TimeInterval = 0
    
    // MARK: New DATE variables using DATECOMPONENTS
    @State var startDate: Date = Calendar.current.date(from: DateComponents(year: 2022, month: 2, day: 4, hour: 11, minute: 00, second: 10)) ?? Date.now
    var endDate: Date = Calendar.current.date(from: DateComponents(year: 2022, month: 2, day: 4, hour: 11, minute: 00, second: 00)) ?? Date.now
    
    // MARK: Calculated TIMEINTERVAL instead of original COUNTTO variable
    var timeInterval: TimeInterval {
        let end = endDate
        let start = startDate
        
        return start.timeIntervalSince(end)
    }
    
    var body: some View {
        NavigationView {
            VStack{
                ZStack{
                    Circle()
                        .fill(Color.clear)
                        .frame(width: 250, height: 250)
                        .overlay(
                            Circle().stroke(Color.green, lineWidth: 25)
                    )
                     
                    Circle()
                        .fill(Color.clear)
                        .frame(width: 250, height: 250)
                        .overlay(
                            Circle().trim(from:0, to: progress())
                                .stroke(
                                    style: StrokeStyle(
                                        lineWidth: 25,
                                        lineCap: .round,
                                        lineJoin:.round
                                    )
                                )
                                .foregroundColor(
                                    (completed() ? Color.orange : Color.red)
                                ).animation(
                                    .easeInOut(duration: 0.2)
                                )
                        )
                    // MARK: Text view for DATE just to show you that timer is working
                    Text("\(startDate.formatted(date: .long, time: .standard))")
                        .font(.system(size: 10))
                        .foregroundColor((timeInterval == 0) ? .orange : .black)
                }
            }
            // MARK: Changed logic for timer calculations
            .onReceive(timer) { time in
                if (timeInterval != 0) {
                    counter += 1
                    startDate -= 1
                }
            }
            
            // MARK: A few changes to the layout
            .navigationTitle("Timer")
            .toolbar {
                Button("Start again", action: startAgain)
            }
        }
    }
    
    // MARK: Function for a START AGAIN button
    func startAgain() {
        counter = 0
        startDate = Calendar.current.date(from: DateComponents(year: 2022, month: 2, day: 4, hour: 11, minute: 00, second: 10)) ?? Date.now
        return
    }
    
    func completed() -> Bool {
        return progress() == 1
    }
     
    func progress() -> CGFloat {
        return (CGFloat(counter) / CGFloat(timeInterval + counter))
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM