Abhi Ram
Abhi Ram

Reputation: 53

Is there a way to update only certain elements in an EnvironmentObject

For example, I would like each list element to be independent of the other's data.

Such that, changing the name of one will not affect the other. But I also want the list to be updated if they are altered from another view.

struct ContentView: View {
    var listView = People()
    let tempPerson = Person()

    var body: some View {
        VStack {
            Button(action: {
                self.listView.people.append(self.tempPerson)
            }){
                Text("Add person")
            }
            ListView().environmentObject(listView)
        }.onAppear{self.listView.people.append(self.tempPerson)}
    }
}

struct ListView : View {
    @EnvironmentObject var listView : People

    var body: some View{
        List(listView.people.indices, id: \.self) { index in
            TextField("StringProtocol", text: self.$listView.people[index].name)
        }
    }
}
class Person {
    var name = "abc"
}

class People : ObservableObject {
    @Published var people : [Person]

    init() {
        self.people = []
    }
}

Upvotes: 1

Views: 51

Answers (1)

pawello2222
pawello2222

Reputation: 54556

Person is a class. Which means if you create:

let tempPerson = Person()

then in every place inside your ContentView you'll refer to the same Person instance - and you'll append the same person in your button action:

Button(action: {
    self.listView.people.append(self.tempPerson)
}) {
    Text("Add person")
}

I recommend you change your Person to be a struct instead of a class:

struct Person {
    var name = "abc"
}

As structs are copied, every time you append a new item:

self.listView.people.append(self.tempPerson)

it will be a copy of the original tempPerson and you'll be able to change your items independently.

You can read more here: Structures and Classes

Upvotes: 1

Related Questions