I have a @Published Date() variable that I want to update every 5 seconds to keep app time in sync.
I tired placing the timer inside the class, but that does not revolve the issue either.
video preview videolink (YouTube)
import SwiftUI
struct ContentView: View {
@State var countdown = Timer.publish(every: 2, on: .current, in: .default).autoconnect()
@ObservedObject var timer = globalTime()
var body: some View {
VStack{
Text("time (timer.currentDate)")
Text("This is a view")
}
.toolbar(content: {
ToolbarItem(id: "help",placement: .navigationBarLeading) {
NavigationLink(
destination: ContentView2(),
label: {
Text("View Link")
})
}
})
.onReceive(countdown, perform: { _ in
timer.currentDate = timer.currentDate.addingTimeInterval(2)
})
}
}
class globalTime: ObservableObject {
@Published var currentDate = Date(timeIntervalSince1970: 12)
}
//NavigationLink View
struct ContentView2: View {
@ObservedObject var global = globalTime()
var body: some View {
VStack{
Text("This is a view")
}
}
}
2
Answers
For starters, you have a
Publisher
stored as a@State
variable, which you shouldn’t be doing. That timer is never modified and should be alet
property, or bound to aPublished
variable, on yourObservableObject
. Second, inContentView2
you have an observable object being set from inside the same view butObservableObject
means that that object’s storage is handled externally, so by assigning the value where it’s declared, you’re violating the observable object contract. If you want to declare it inside your view, use@StateObject
;ObservableObject
is used when you pass view models down to children views. In that case, the parent is responsible for the view models storage so that when the child reloads, it doesn’t also reload the view model.I ran your code and I am not getting multiple navigation link pushes like your video shows. If you’re still experiencing the issue, try a couple things:
@ObservableObject
to@StateObject
there are a number of issues with your code. You need a
NavigationView
to beable to use a
NavigationLink
. Also you need to pass thetimer
to your next ViewContentView2
for it to be available in that view. The following code shows someof these concepts.