Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
3.9k views
in Technique[技术] by (71.8m points)

swift - 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:

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

View B:

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

View C:

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:

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

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!

EDIT

Things I tested.

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)
等待大神答复

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...