UPGRADE YOUR SKILLS: Learn advanced Swift and SwiftUI on Hacking with Swift+! >>

Published Int not updating Text

Forums > Swift

I have the following class

class StopWatchManager: ObservableObject {

    @Published var secondsElapsed: Int = 0

    var timer = Timer()

    func start() {
        timer = Timer.scheduledTimer(withTimeInterval: 1, repeats: true) { timer in
            self.secondsElapsed += 1
        }
    }
}

And a view (Header of a screen) with a text that displays the time...

fileprivate struct Header: View {

  @ObservedObject var stopWatchManager = StopWatchManager()

  var body: some View {
    ...

    Text("Tempo: \(stopWatchManager.secondsElapsed)")
                .foregroundColor(Color("primaryColor"))
                .font(.custom("Lato-Bold", size: 20))
  }
  .onAppear(perform: {
            stopWatchManager.start()
  })
}

I can not understand why the counter remains stick to 0. I also checked with a print() and the timer starts correctly. It seems that the variable secondsElapsed is not published.

Any tip to solve? Thanks in advance for the answer!

3      

Your onAppear is not attached properly. It should be attached to something inside the body property but you have it attached to the body itself.

3      

@roosterboy but the timer is starting aniway. I checked with a simple print below self.secondsElapsed += 1 (i did print(self.secondsElapsed) and it was printing every seconds correctly.

3      

Then the code you posted must not be the code you are actually using, because the code you posted will not even compile due to the misplaced onAppear.

I took your code, moved the onAppear to where it belonged and then removed the foregroundColor and font modifiers since I don't have the same resources in my test project. I also took out the fileprivate access control label since my App struct is in another file and otherwise it wouldn't be able to see the View. I ended up with this:

struct Header: View {

    @ObservedObject var stopWatchManager = StopWatchManager()

    var body: some View {
        Text("Tempo: \(stopWatchManager.secondsElapsed)")
            .onAppear(perform: {
                stopWatchManager.start()
            })
    }
}

And it worked perfectly.

stopwatch

3      

TAKE YOUR SKILLS TO THE NEXT LEVEL If you like Hacking with Swift, you'll love Hacking with Swift+ – it's my premium service where you can learn advanced Swift and SwiftUI, functional programming, algorithms, and more. Plus it comes with stacks of benefits, including monthly live streams, downloadable projects, a 20% discount on all books, and free gifts!

Find out more

Sponsor Hacking with Swift and reach the world's largest Swift community!

Archived topic

This topic has been closed due to inactivity, so you can't reply. Please create a new topic if you need to.

All interactions here are governed by our code of conduct.

 
Unknown user

You are not logged in

Log in or create account
 

Link copied to your pasteboard.