Arif Ata Cengiz
Arif Ata Cengiz

Reputation: 93

SwiftUI: Published string changes inside view model are not updating view

I have a timer inside my view model class which every second changes two @Published strings inside the view model. View model class is an Observable Object which Observed by the view but the changes to these string objects are not updating my view.

I have a very similar structure in many other views(Published variables inside a ObservableObject which is observed by view) and it always worked. I can't seem to find what am I doing wrong?

ViewModel

final class QWMeasurementViewModel: ObservableObject {

    @Published var measurementCountDownDetails: String = ""
    @Published var measurementCountDown: String = ""

    private var timer: Timer?
    private var scheduleTime = 0

    func setTimer() {
        timer = Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true) { timer in
            DispatchQueue.main.async {
                self.scheduleTime += 1
                if self.scheduleTime == 1 {
                    self.measurementCountDownDetails = "Get ready"
                    self.measurementCountDown = "1"
                }
                else if self.scheduleTime == 2 {
                    self.measurementCountDownDetails = "Relax your arm"
                    self.measurementCountDown = "2"
                }
                else if self.scheduleTime == 3 {
                    self.measurementCountDownDetails = "Breathe"
                    self.measurementCountDown = "3"
                }
                else if self.scheduleTime == 4 {
                    self.measurementCountDownDetails = ""
                    self.measurementCountDown = ""
                    timer.invalidate()
                }
            }
        }
    }
}

View

struct QWMeasurementView: View {
    @ObservedObject var viewModel: QWMeasurementViewModel

    var body: some View {
        VStack {
            Text(viewModel.measurementCountDownDetails)
                .font(.body)
            Text(viewModel.measurementCountDown)
                .font(.title)
        }
        .onAppear {
            viewModel.setTimer()
        }
    }
}

Edit

After investigation, this seems to be related to how it is being presented. Cause if it's a single view this code works but I am actually presenting this as a sheet. (Still cannot understand why would it make a difference..)

struct QWBPDStartButtonView: View {

    @ObservedObject private var viewModel: QWBPDStartButtonViewModel
    @State private var startButtonPressed: Bool = false

    init(viewModel: QWBPDStartButtonViewModel) {
        self.viewModel = viewModel
    }

    var body: some View {
        Button(action: {
            self.startButtonPressed = true
        }) {
            ZStack {
                Circle()
                    .foregroundColor(Color("midGreen"))
                Text("Start")
                    .font(.title)
            }
        }
        .buttonStyle(PlainButtonStyle())
        .sheet(isPresented: $startButtonPressed) {
            QWMeasurementView(viewModel: QWMeasurementViewModel())
        }
    }
}

Upvotes: 0

Views: 1896

Answers (1)

Gene De Lisa
Gene De Lisa

Reputation: 3838

You’re passing in a brand new viewmodel to the sheet’s view. Try passing in the instance from line 3

Upvotes: 0

Related Questions