1

I have an Object like this (simplified):

struct BoxModel: Codable, Identifiable, Hashable {
    var id: Int
    var number: Int
}

I have a two dimensional array of these:

@State private var matrix = generate()

where generate creates a 2D array of the objects: [[BoxModel]]. I then display them in a grid. The grid is pretty complex but here's a very simplified form:

LazyVGrid(columns: columns, spacing: 0 ) {
    ForEach(1...9, id: \.self) { j in
         Text("\(getModel(j).number)")
    }
}

Where getValue gets the item from the array that corresponds to the grid location. Since the grid is complex, I need to do some arithmetic in a separate function to do this.

Below this is a button. When the user taps it, it changes the number property of one of the objects in the array. However, the number doesn't update. I thought it would since the array is a @State property.

Is there a way to make it update?

Here's an extremely simplified form of the ContentView:

struct ContentView: View {

@State private var matrix = generate()


var body: some View {
    NavigationView {
        GeometryReader { geometry in
            ScrollView {
                VStack {

                    let columns = [GridItem(.fixed(50), spacing: 0),
                                     GridItem(.fixed(50), spacing: 0),
                                     GridItem(.fixed(50), spacing: 0)]
                    

                    LazyVGrid(columns: columns, spacing: 0 ) {
                        ForEach(1...9, id: \.self) { j in
                            Text("\(getModel(j).number)")
                        }
                    }
                    .padding()
                    Button {
                        var model = getModel(0)
                        model.number = 5
                    } label: {
                        Text("Click Me")
                    }
                }
            }
        }
    }
}


func getModel(_ i: Int) -> BoxModel {
    // very simplified
    return matrix[0][i]
}
0

1 Answer 1

2

In summary, the code in your Button closure is creating a new Object which is different/not related to the matrix variable. So updating the new Object won't affect the @State variable.

Change the code in your Button action closure, from:

var model = getModel(0)
model.number = 5

to

if let index = matrix[0].firstIndex(of: getModel(1)) {
    matrix[0][index].number = 5
}

The goal is to make sure you're updating/changing the @State property itself.

Sign up to request clarification or add additional context in comments.

1 Comment

That's a little difficult since that would mean I need to create a new function to change the number which is almost exactly the same as the func to get the model (since its a lot more complex than matrix[0][i]). But I get it, the actual state property has to change. Thank you.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.