Содержимое списка SwiftUI сбрасывается при выборе

#swiftui #swiftui-list #swiftui-environment

#swiftui #swiftui-список #swiftui-среда

Вопрос:

Вот моя проблема: MainView отображает ChildView и предоставляет ему EnvironmentObject список, содержащий набор выбранных элементов.

ChildView отображает список выбираемых элементов (2 элемента в примере) и загружает список при появлении.

Проблема в том, что ChildView содержимое сбрасывается до исходного значения (1 элемент в примере), когда я нажимаю на любую строку.

Я попытался сделать свой код как можно более компактным.

 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
}
 

Нет проблем, если я не использую объект среды, но не понимаю, как это приводит к сбросу списка.

Ответ №1:

Вы изменяете MainViewModel , и это приводит к перестройке тела, в том числе ChildView .

Если у вас установлена iOS 14 в качестве целевой минимально поддерживаемой системы, самым простым решением является использование StateObject , поскольку оно сохраняет данные просмотра

 struct ChildView : View {
    
    @StateObject var cm = ChildViewModel()     // << here !!

    // ... other code
 

Комментарии:

1. Каковы возможные решения для iOS13? Хранить мои объекты где-то еще?