Kai faces a common problem:
Error: Cannot use mutating member on immutable value: 'self' is immutable.
I would be very grateful is someone could explain where my misunderstanding lies
Think of a struct
as a box.
You put variables and functions inside the box.
But a struct
box is made of cement. Once the box is created, built, and on screen, you cannot change it. It is hard cement. It is immutable.
If you want a different version of the box, SwiftUI destroys the old version and creates a new, modified version for you. This seems wasteful, but SwiftUI is very efficient.
But what about the data inside the cement box?
The array of integers? How do we keep track of that array and add new values to it?
In Swift, you store those values OUTSIDE of the cement box. But you keep a reference inside the box. A simple way to do this is with @State
variables.
You tell your cement box to build itself, but to use the data that is stored in an external @State
variable, you can then change the variable adding new values as necessary.
Try this in Playgrounds:
import SwiftUI
import PlaygroundSupport
struct CementBoxView: View {
// Stored outside of this box.
@State private var boxParts: [Int] = []
@State private var numberString = ""
var body: some View {
VStack {
TextField("Part", text: $numberString)
.onSubmit {
boxParts.append( Int(numberString) ?? 0 )
numberString = ""
}
Spacer()
ForEach( boxParts, id: \.self) { Text("\($0)") }
}.frame(height: 300)
}
}
PlaygroundPage.current.setLiveView( CementBoxView() )