Search code examples
iosswiftswiftuixcode11

SwiftUI call mutating func from var body


In the tutorial from Ray that I'm following I have the following properties set

struct ContentView : View {

    var rTarget = Double.random(in: 0..<1)
    var gTarget = Double.random(in: 0..<1)
    var bTarget = Double.random(in: 0..<1)
}

These are of course immutable so I can't modify them from a func unless I mark that func as mutating

func reset() {
    rTarget = Double.random(in: 0..<1)
    gTarget = Double.random(in: 0..<1)
    bTarget = Double.random(in: 0..<1)
}

Cannot assign to property: 'self' is immutable

But I call this func from var body

mutating func reset() {
    rTarget = Double.random(in: 0..<1)
    gTarget = Double.random(in: 0..<1)
    bTarget = Double.random(in: 0..<1)
}

fileprivate mutating func displayAlert() -> Alert {
    return Alert(title: Text("Your Score"), message: Text("\(computeScore())"), dismissButton: Alert.Button.destructive(Text("Ok"), onTrigger: {
        self.reset()
    }))
}

 var body: some View {
    Button(action: {
        self.showAlert = true
    }) {
        Text("Hit Me!")
        }.presentation($showAlert) {
            displayAlert()
    }
}

Cannot use mutating member on immutable value: 'self' is immutable

But I can't mark var body as mutating var

'mutating' may only be used on 'func' declarations

So at this point, I want to reset the xTarget values each time the user taps on the alert button and I don't know what a good practice will be at this point.


Solution

  • I was working on the same article.

    I didn't get this problem because I was already using the @State property wrapper. As suggested by kontiki Session 226 (Data Flow Through SwiftUI) is great for understanding how to use which property wrapper when you are updating the data different source.

    And If you want to know what is @State this answer has it all.

    Here is my code:

    @State var rTarget = Double.random(in: 0..<1)
    @State var gTarget = Double.random(in: 0..<1)
    @State var bTarget = Double.random(in: 0..<1)
    @State var rGuess: Double
    @State var gGuess: Double
    @State var bGuess: Double