swiftswiftui

How to stop timer in Text view?


It is possible to pass a date to Text() in SwiftUI, then format it as a timer using the style argument. However, a countdown like this never stops, it just keeps incrementing after zero. How to make it stop at 0?

func nextRollTime(in seconds: Int) -> Date {
    let date = Calendar.current.date(byAdding: .second, value: seconds, to: Date())
    return date ?? Date()
}

Above is the function I use to start a countdown, then I pass it as follows:

Text(nextRollTime(in: 20), style: .timer)


Solution

  • Here is a demo of possible approach - as .timer run from now for ever (by design), the idea is to replace it with regular text once specified period is over.

    Tested with Xcode 12b3 / iOS 14.

    demo

    struct DemoView: View {
        @State private var run = false
    
        var body: some View {
            VStack {
                if run {
                    Text(nextRollTime(in: 10), style: .timer)
                } else {
                    Text("0:00")
                }
            }
            .font(Font.system(.title, design: .monospaced))
            .onAppear {
                self.run = true
            }
        }
    
        func nextRollTime(in seconds: Int) -> Date {
            let date = Calendar.current.date(byAdding: .second, value: seconds, to: Date())
            DispatchQueue.main.asyncAfter(deadline: .now() + Double(seconds)) {
                self.run = false
            }
            return date ?? Date()
        }
    }