SwiftUI 列表内容通过选择重置

Posted

技术标签:

【中文标题】SwiftUI 列表内容通过选择重置【英文标题】:SwiftUI List content gets reset with selection 【发布时间】:2020-11-23 11:28:02 【问题描述】:

这是我的问题: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

【讨论】:

对于iOS13,可能的解决方案是什么?将我的对象存储在其他地方?

以上是关于SwiftUI 列表内容通过选择重置的主要内容,如果未能解决你的问题,请参考以下文章

SwiftUI List 在任何视图更改时重置滚动

在 SwiftUI 列表中选择多个项目

如何使用 SwiftUI 重置子视图状态变量?

在列表中切换选择 - SwiftUI

SwiftUI 如何创建选择列表的 LazyVStack

当我通过鼠标单击更改 SwiftUI 列表的选择时,@Published 属性的 didSet 被调用了两次