Most idiotic problem with assign value to value?

Why assigning function.formula = formula does not change function.formula to formula in one go? It's always late one change behind. struct CustomFunction has defined .formula as @MainActor.

I feel stupid.

There is a part of code:

struct CustomFormulaView: View {
     @Binding var function: CustomFunction
     @State var testFormula: String = ""
     @EnvironmentObject var manager: Manager

....
         .onChange(of: testFormula) {  
                debugPrint("change of test formula: \(testFormula)") 
                switch function.checkFormula(testFormula, on: manager.finalSize) {
                case .success(let formula): 
                    debugPrint("before Change: \(function.formula)")
                    function.formula = formula // Nothing happens
                    debugPrint("Test formula changed: \(testFormula)")
                    debugPrint("set to success: \(formula)")
                    debugPrint("what inside function? \(function.formula)")
                    
                    Task {
                        //Generate Image
                        testImage = await function.image(
                            size: testImageSize), 
                            simulate: manager.finalSize)
                        debugPrint("test image updated for: \(function.formula)")
                    }
....

and it produces this output when changed from 0.5 to 1.0

Debug:  change of test formula: 1.0
Debug:  before Change: 0.5
Debug:  Test formula changed: 1.0
Debug:  set to success: 1.0
Debug:  what inside function? 0.5
Debug:  test image updated for: 0.5

0.5 is an old value, function.formula should be 1.0

WT??

Answered by ludzik in 815043022

Bindings in superview was defined inside body.

It would be so much easier if you provided simple and complete reproducible code…

So I recreated a simple test code:

enum ResultType {
    case success(formula: Float)
    case failure
}

struct CustomFunction {
    var formula: Float = 0.5
    
    func checkFormula(_ formula: Float) -> ResultType {
        if formula > 0 {
            return .success(formula: formula)
        }
        return .failure
    }
}

struct CustomFormulaView: View {
    @Binding var function: CustomFunction
    @State var testFormula: Float = 0
    
    var body: some View {
        
        HStack {
            Text("    test formula ")
            TextField("", value: $testFormula, format: .number)
        }
        .onChange(of: testFormula) {
            debugPrint("change of test formula: \(testFormula)")
            switch function.checkFormula(testFormula) {
                case .success(let formula):
                    debugPrint("before Change: \(function.formula)")
                    function.formula = formula // Nothing happens
                    debugPrint("Test formula changed: \(testFormula)")
                    debugPrint("set to success: \(formula)")
                    debugPrint("what inside function? \(function.formula)")
                    /*
                     Task {
                     //Generate Image
                     testImage = await function.image(
                     size: testImageSize),
                     simulate: manager.finalSize)
                     break              debugPrint("test image updated for: \(function.formula)")
                     }
                     */
                    
                case .failure :
                    print("failed") ; break
            }
        }
    }
}

struct ContentView: View {
    @State var function = CustomFunction()

    var body: some View {
        CustomFormulaView(function: $function)
        Text("\(function.formula)")
    }
}

And get what I understand is the expected result

"change of test formula: 2.0"
"before Change: 0.5"
"Test formula changed: 2.0"
"set to success: 2.0"
"what inside function? 2.0"
Accepted Answer

Bindings in superview was defined inside body.

Thanks for the feedback.

Just shows you should post complete code. This would have been obvious and avoided we loos time to search.

Most idiotic problem with assign value to value?
 
 
Q