I would like to pass a timer from ContentView
to SecondView
, but I don’t know how to manage it because I never used it before.
Can someone figure this out for me?
ContentView
struct ContentView: View {
@State private var timer = Timer.publish(every: 1, tolerance: 0.5, on: .main, in: .common).autoconnect()
@State private var timeRemaining = 10
var body: some View {
NavigationView {
VStack {
Text("(timeRemaining)")
.onReceive(timer) { _ in
if timeRemaining > 0 {
timeRemaining -= 1
}
}
NavigationLink {
SecondView(timer: ???) // <-- What should i pass here?
} label: {
Text("Change View")
}
}
}
}
}
SecondView
struct SecondView: View {
@Binding var timer: ??? // <-- What type?
@State private var timeRemaining = 5
var body: some View {
Text("Hello")
.onReceive(timer) { _ in
if timeRemaining > 0 {
timeRemaining -= 1
}
}
}
}
struct SecondView_Previews: PreviewProvider {
static var previews: some View {
SecondView(timer: ???) // <-- Same thing here in SecondView preview
}
}
3
Answers
With this timer declaration you are in the
Combine
world.Combine
is the reactive framework from Apple.First you would need to import it:
I have commented the code but
Combine
is a far field and it probably would be best to read the documentation about it, read some tutorials and try some things out.documentation
You could simply inject the timer publisher, as suggested above, but there may be an even simpler solution:
FirstView
is already updating with every tick of the timer. You could simply pass atimeRemaning
binding to your second view and then it too would just update with every tick of the timer (becausetimeRemaining
changes on each tick). You can then observe and react to changes oftimeRemaining
using .onChange(of:):You don’t need to pass a binding, Since you are not mutating timer of contentview from the second view. You can just pass the reference to the timer publisher and then subscribe to it using
.onReceive()
.