Currently creating a SwiftUI app, I got stuck trying to solve a problem with a ObservedObject and a picker. My ContentView:
struct ContentView: View {
@ObservedObject var timerManager = TimerManager()
...
var body: some View{
Circle()
.onTapGesture(perform: {
self.timerManager.setTimerLength(seconds: self.settings.selectedSecondPickerIndex, minutes: self.settings.selectedMinutePickerIndex)
self.timerManager.start()
})
Picker(selection: self.$settings.selectedSecondPickerIndex, label: Text("")) {
ForEach(0 ..< 60) {
Text("\(secondsToString(seconds: self.availableTimeInterval[$0]))")
}
}
}
...
}
The TimerManager manages a timer. The class:
class TimerManager: ObservableObject {
@Published var secondsLeft : Int = -1
var secondsTotal : Int = -1
var timer = Timer()
func start() {
timer = Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true, block: { timer in
if secondsLeft == 0 {
self.secondsLeft = secondsTotal
timer.invalidate()
}
else{
self.secondsLeft -= 1
}
}
RunLoop.current.add(timer, forMode: RunLoop.Mode.common)
}
func setTimerLength(seconds: Int, minutes: Int) {
let totalSeconds: Int = seconds + minutes * 60
secondsTotal = totalSeconds
secondsLeft = totalSeconds
}
...
}
I need to access the secondsLeft variable of the timer class from ContentView to display the remaining time. When the timer runs, the secondsLeft variable gets updated every second and ContentView gets rerendered. The problem is that while the timer is running, I can't "flick" my picker, it always resets, also pointed out here: https://forums.developer.apple.com/thread/127218. But unlike in that post, the "selection" variable of the picker doesn't have any effect on the problem. If I remove the @Public from the secondsLeft variable, everything works just fine (problem is that I can't display the remaining time then).
Does anybody have an idea how to solve this?
Thanks for answering!