skip to Main Content

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


  1. 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 a let property, or bound to a Published variable, on your ObservableObject. Second, in ContentView2 you have an observable object being set from inside the same view but ObservableObject 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:

    • define your timer publisher on the observable object
    • change @ObservableObject to @StateObject
    Login or Signup to reply.
  2. there are a number of issues with your code. You need a NavigationView to be
    able to use a NavigationLink. Also you need to pass the timer to your next View
    ContentView2 for it to be available in that view. The following code shows some
    of these concepts.

    struct ContentView: View {
        let countdown = Timer.publish(every: 2, on: .current, in: .default).autoconnect()
        
        @StateObject var timer = globalTime() // <-- here
        
        var body: some View {
            NavigationView {
                VStack{
                    Text("time (timer.currentDate)")
                }
                .toolbar {
                    ToolbarItem(id: "help", placement: .navigationBarLeading) {
                        NavigationLink(destination: ContentView2(global: timer)) {
                            Text("View Link")
                        }
                    }
                }
                .onReceive(countdown) { _ in
                    timer.currentDate = timer.currentDate.addingTimeInterval(2)
                }
            }
        }
    }
    
    class globalTime: ObservableObject {
        @Published var currentDate = Date(timeIntervalSince1970: 12)
    }
    
    struct ContentView2: View {
        @ObservedObject var global: globalTime  // <-- here
        
        var body: some View {
            VStack{
                Text("This is a view")
                Text("time (global.currentDate)")  // <-- here
            }
        }
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search