0

enter image description here

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()
        }
  • 1
    Agree with the above -- without any code, it's too vague to try to "solve" here – jnpdx Feb 16 '23 at 17:13
  • At least edit your question to include the code of the reset function and the code that calls the reset function. – rob mayoff Feb 16 '23 at 17:14
  • 1
    @PaulBrankin adding the code helps, but there's _way_ too much. The first word of [mcve] is "minimal", so only include code that's relevant to the issue. Remove all the any views or model code that isn't causing issues. – Ashley Mills Feb 16 '23 at 19:19
  • 1
    @AshleyMills Many thanks for your guidance. Hopefully the current edit is a little less painful. – Paul Brankin Feb 16 '23 at 19:41
  • 1
    @PaulBrankin it's better, but try removing irrelevant view modifiers, i.e. `fontWeight`, and simplifying your `resetGolfController` function so that there aren't so many things happening, only relevant things :) – Stoic Feb 16 '23 at 19:54
  • 1
    Ok. Thanks again. I shall shortly post a better, simplified code example that is testable. – Paul Brankin Feb 16 '23 at 20:01
  • Your code is appreciated. Be sure to add the ObservableObject and @StateObject's declaration for more context about how your code is organized. – Marcy Feb 16 '23 at 21:59
  • Many thanks for those that guided. 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). Thanks. – Paul Brankin Feb 17 '23 at 13:15
  • @PaulBrankin For readability, you could also post your solution as an answer to your own question. – koen Feb 17 '23 at 13:20

0 Answers0