SwiftUI: Question about SwiftUI's Lifecyle, I think… Object isn't created properly

I'm new to SwiftUI and I have run into an issue I can't explain.

(I know its a lot of text but it would be great if you can help me)

About the project: For the problem three views are important. In View A you can set some values and when you press a button you go to the View C where an object is created with the passed values form View A. In this example every things work, the values are presented in a Text View.
There is also the option to save the values you set in View A and save them to use them later. These objects are saved and when you tap on them in View 0 (View is a view where every saved object is presented)you get to ViewB. There you can go to View C like in View A. Here the values should also be displayed but don't. Only when I press a button in View C do the values appear.

Code:

View A:
Code Block
NavigationLink(destination: TrainingView(trainingsListVM: übungListVM.transformToTrainingsListVM(daten: daten))){
Text("startString")
.styleButton()
} //goes to View C an passes the necessary values

View B:
Code Block
NavigationLink(destination: TrainingView(trainingsListVM: workout.transformToTrainingsListViewModel())){
Text("startString")
.styleButton()
}

View C:
Code Block
struct ViewC: View{
var trainingsListVM: TrainingsListViewModel
@ObservedObject var settings = SettingsModel()
//intervallTimer is the important Object
@ObservedObject var intervallTimer = IntervallTimer(trainingsListVM: TrainingsListViewModel(daten: Daten()), settings: SettingsModel())
var momentaneÜbung: String{ //one of the values I want to display
if !noExercise{
return intervallTimer.momentaneÜbung
}else{
return NSLocalizedString("\(intervallTimer.inTraining ? "trainingString" : "pauseString")", tableName: "Localizable", comment: "")
}
}
init(trainingsListVM: TrainingsListViewModel) {
self.trainingsListVM = trainingsListVM
intervallTimer = IntervallTimer(trainingsListVM: trainingsListVM, settings: settings)
//have to set intervalltimer here again because I need the passes object trainingsListVM which I get from View A or View B
}
var body: some View{
Text(momentaneÜbung) //when I come from View A momentaneÜbung has a value; from View B it is empty on the screen
.onApperar{
intervallTimer.setStart()//set the right values
print(momentaneÜbung) //although it is not shown on the screen, the correct value is sprinted here (when I come from View B)
}
}
}

IntervallTimer Object:

Code Block
class IntervalTimer: ObervableObject{
var trainingsListVM: TrainingsListViewModel
var settings: SettingsModel
@Published var trainingsState: [TrainingsState] = []
@Published var übungenListe: Übungen
init(trainingsListVM: TrainingsListViewModel, settings: SettingsModel) {
self.settings = settings
übungenListe = Übungen(trainingsListVM: trainingsListVM)
self.trainingsListVM = trainingsListVM
if settings.randomExercise == true{
self.übungenListe.übungen.shuffle()
//this init is called when I go to View B but I use it in View C. Shouldn't it only be created when I go to View C
}
}
var momentaneÜbung = ""
...some other variables
func setStart(){
trainingsState = []
trainingsState = setTrainingsState(übungenListe: übungenListe)
momentaneÜbung = übungenListe.übungen[0].name //String array with all exercises
trainingsState.removeFirst()
}
}



Things I tested:
  • When I call onAppear() in View C an print the value it is printed correctly.

  • When I set a breakpoint in the init() of the object I want to create in View C it gets already called when I go to View B

  • When I set a breakpoint in the init of intervallTimer and go to View C (coming from View B) this init is called 7 times. In every iteration I print momentaneÜbung. In the first five iterations momentaneÜbung is empty, in the sixth I get the right value but in the last one momentaneÜbung is empty again.

Question: What is the reason for the different behaviour depending on which view I come from?

I hope I have mentioned everything important. I am very happy to receive an answer. Thank you!

What is the reason for the different behaviour depending on which view I come from?

I cannot answer to your question directly.
But one thing is sure:
  • You should not rely on when initializers of Views are called.

The runtime of SwiftUI may evaluate body and may call the initializer of a View at anytime it is needed.
You need to accept this fact when you write code in SwiftUI.
SwiftUI: Question about SwiftUI's Lifecyle, I think… Object isn't created properly
 
 
Q