I implemented this custom countdown DatePicker that I found on stack overflow here's the link but it has a bug where if I change the picker from something different then 1 minute the first time I start the timer it'll still set the timer to one minute, but if I change it after that first time it works fine.
import SwiftUI
struct DurationPicker: UIViewRepresentable {
@Binding var duration: Double
func makeUIView(context: Context) -> UIDatePicker {
let datePicker = UIDatePicker()
datePicker.datePickerMode = .countDownTimer
datePicker.addTarget(context.coordinator, action: #selector(Coordinator.updateDuration), for: .valueChanged)
return datePicker
}
func updateUIView(_ datePicker: UIDatePicker, context: Context) {
datePicker.countDownDuration = duration
}
func makeCoordinator() -> Coordinator {
Coordinator(self)
}
class Coordinator: NSObject {
let parent: DurationPicker
init(_ parent: DurationPicker) {
self.parent = parent
}
@objc func updateDuration(datePicker: UIDatePicker) {
parent.duration = datePicker.countDownDuration
}
}
}
struct ContentView: View {
@State var duration = 60.0
@State var timeRemaining = 60.0
@State private var isActive = false
var timer = Timer.publish(every: 1, on: .main, in: .common).autoconnect()
var body: some View {
VStack {
Text("\(timeRemaining)")
.bold()
.font(.largeTitle)
DurationPicker(duration: $duration)
HStack {
Button("Cancel") {
isActive = false
}
.padding()
Button("Start") {
self.timeRemaining = duration
isActive = true
}
.padding()
}
}
.onReceive(timer) { time in
guard self.isActive else { return }
if self.timeRemaining > 0 {
self.timeRemaining -= 1
}
}
.onReceive(NotificationCenter.default.publisher(for: UIApplication.willResignActiveNotification)) { _ in
self.isActive = false
}
.onReceive(NotificationCenter.default.publisher(for: UIApplication.willEnterForegroundNotification)) { _ in
self.isActive = true
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
I'm not quite sure what to set meditateTime as, I thought @State would automatically change it if it did change so I'm not quite sure what's going on.