jwarris91
jwarris91

Reputation: 952

Stopping a SwiftUI Widget's relative textfield counter when hits zero?

I am creating a Widget that has a textfield that counts down from a date like so:

Text(endDate, style: .relative)

This works fine, however as its relative, once it hits zero, it will continue to count back up again as the endDate becomes in the past.

Is there a way to terminate the text when it hits zero? Or do I have to rebuild this feature with a timer?

All I need to do is count down from a start date to and end date then invalidate the text field or show a message.

Upvotes: 3

Views: 808

Answers (3)

tsuboyan
tsuboyan

Reputation: 11

Since iOS 16, it is now possible to stop at 0 by setting the 'countsDown' argument of Text to true.

https://developer.apple.com/documentation/swiftui/text/init(timerinterval:pausetime:countsdown:showshours:)

Upvotes: 1

pawello2222
pawello2222

Reputation: 54516

Here is how you can create a countdown and when the time is over display some other text.

  1. Create an Entry where endDate is optional - if it's nil it means that the countdown is over:
struct SimpleEntry: TimelineEntry {
    let date: Date
    var endDate: Date?
}
  1. In your Provider create two Entries - one for the countdown time and one for when the countdown is over:
struct SimpleProvider: TimelineProvider {
    ...

    func getTimeline(in context: Context, completion: @escaping (Timeline<SimpleEntry>) -> Void) {
        let currentDate = Date()
        let endDate = Calendar.current.date(byAdding: .second, value: 15, to: currentDate)!

        let entries = [
            SimpleEntry(date: currentDate, endDate: endDate),
            SimpleEntry(date: endDate),
        ]

        let timeline = Timeline(entries: entries, policy: .never)
        completion(timeline)
    }
}
  1. Use it in your view:
struct WidgetEntryView: View {
    var entry: Provider.Entry

    var body: some View {
        if let endDate = entry.endDate {
            Text(endDate, style: .relative)
        } else {
            Text("Timer finished")
        }
    }
}

Upvotes: 5

Joseph Lord
Joseph Lord

Reputation: 6504

I think you have to schedule a widget update at time zero and have conditions to hide it when less than zero.

Upvotes: 0

Related Questions