Here is my issue: MainView displays ChildView and gives it an EnvironmentObject containing a set of selected items.
ChildView displays a list of selectable items(2 items in the example), and load the list when appearing.
The problem is that the ChildView content is reset to its original value (1 item in the example) when I tap on any row.
I tried to make my code as compact as possible.
struct MainView: View {
@ObservedObject var model = MainViewModel()
var body: some View {
NavigationView {
ChildView().environmentObject(self.model)
}
}
}
class MainViewModel: ObservableObject {
@Published var selection = Set<Stuff>()
var formatted: String {
return "\(self.selection.count)"
}
}
struct ChildView : View {
@ObservedObject var cm = ChildViewModel()
@EnvironmentObject var model: MainViewModel
var body: some View {
VStack(spacing: 0) {
List(cm.demoData, id: \.self, selection: $model.selection) { stuff in
Text("\(stuff.value)")
}
.environment(\.editMode, .constant(EditMode.active))
.onAppear(perform: cm.load)
}
}
}
class ChildViewModel : ObservableObject {
@Published var demoData: [Stuff] = [Stuff(id: 1, value: "1")]
func load() {
self.demoData = [Stuff(id: 1, value: "1"), Stuff(id: 2, value: "2")]
}
}
struct Stuff : Identifiable, Equatable, Hashable {
var id: Int
var value: String
}
There is no problem if I don't use an environment object, but don't get how that causes the list to reset.
You modify
MainViewModeland it cause rebuild body, includingChildView.If you have iOS 14 as target minimal supported system the simplest solution is to use
StateObjectas it preserves view data