Reputation: 11
I have finally managed to resolve my issue. It was caused by depending on .onappear to set ObservableObject properties, rather than using an explicit prior user action with a button (for example).
This was the issue....
I created a StateObject in the "App" file that is an instance of a class called "Controller". Controller contains structs, functions etc that are shared across a number of views.
All views get access to the StateObject through an EnvironmentObject. Views are navigated in sequence using NavigationViews and NavigationLinks. All views call functions and read values of the Controller. Any value changes are conducted entirely within the Controller itself.
My problem is that; When I complete this sequence of Views, I want to reset the state of the Controller. Doing this will enable the user to cycle through the process as many times as needed.
However, whenever I reset state of the Controller using a class level function (called from .onappear in the ContentView), the app immediately navigates to View 2 and ignores the state reset I've invoked. It preserves the previous values that belonged to the Controller. I can see through debugging that it does briefly use the reset values but then instantly reverts to the previously held values.
Can anyone provide any insight as to what might be happening here?
Many thanks.....
I tried to reset the state of a StateObject so that I could re-cycle through my app. Unfortunately, the reset does not work and views with EnvironmentObjects seem to want to preserve the previous state!
This is the code for the view that insists I cannot change then StateObject...
import SwiftUI
struct InPlay: View {
var myCourseId:Int = -1
@EnvironmentObject var golfController: GolfController
var body: some View {
VStack (spacing: 5){
VStack{
Text("\(golfController.golfData.course[golfController.courseIndex].name)").offset(x:0, y:0)
.font(.system(size: 20))
.foregroundColor(golfController.roundFinished ? .gray : GolfColor.golfBlue)
.frame(maxWidth: .infinity, alignment: .leading).offset(x:12, y:-5)
}
HStack(spacing:35){
HStack(spacing: 0){
Text("\(golfController.thisRound.holes[golfController.holeIndex].holeStrokes)")
.gesture(tapGesture)
.font(.system(size: 65))
.fontWeight(.thin)
.frame(width: 200, height: 100)
.frame(maxWidth: .infinity, alignment: .center)
.foregroundColor(golfController.roundFinished ? .gray : golfController.editMode ? GolfColor.golfGreen : GolfColor.golfBlue)
.position(x: 35, y: 0).disabled(golfController.roundFinished)
}
}.offset(y:0)
}.environmentObject(golfController)
.onAppear{
golfController.resetGolfController()
}
.navigationBarTitle("")
.navigationBarBackButtonHidden(true)
.navigationBarHidden(true)
}
struct InPlay_Previews: PreviewProvider {
static var previews: some View {
InPlay(myCourseId: 0)
}
}
}
And this is the reset function within the controller...
func resetGolfController()
{
calculatedPar = ""
parColor = Color.black
selectedCoursename = ""
courseId = 0
courseIndex = 0
holeIndex = 0 // - a problem
showingPinConfirmation = false
showingDropConfirmation = false
showingQuitConfirmation = false
currentHole = 0
editMode = false
scorecardScore = 0
roundFinished = false
storePin = false
holeParPrefix = ""
storePin = false
holeParPrefix = ""
thisRound = Round(startTimestamp: "", endTimestamp: "", roundScore: 0, roundPar: "0", holes: [RoundHole(holeNum: 1, holeStrokes: 0, holePar: "-", strokes: [])])
golfData.readFromFile()
}
Upvotes: 0
Views: 107