从不同视图添加新项目时,SwiftUI ObservedObject 不会更新

Posted

技术标签:

【中文标题】从不同视图添加新项目时,SwiftUI ObservedObject 不会更新【英文标题】:SwiftUI ObservedObject does not updated when new items are added from a different view 【发布时间】:2020-07-10 20:05:54 【问题描述】:

我有一个视图模型,它在应用启动和添加新项目时处理新数据的加载。从新视图添加时显示新项目时遇到问题,例如sheet 甚至NavigationLink

查看模型

class GameViewModel: ObservableObject 
    //MARK: - Properties
    @Published var gameCellViewModels = [GameCellViewModel]()
    var game = [GameModel]()
    
    init() 
        loadData()
    
    
    func loadData() 
        if let retrievedGames = try? Disk.retrieve("games.json", from: .documents, as: [GameModel].self) 
            game = retrievedGames
        
        
        self.gameCellViewModels = game.map  game in
            GameCellViewModel(game: game)
        
        print("Load--->",gameCellViewModels.count)
    
    
    func addNew(game: GameModel)
        self.game.append(game)
        saveData()
        loadData()
    
    
    private func saveData() 
        do 
            try Disk.save(self.game, to: .documents, as: "games.json")
        
        catch let error as NSError 
            fatalError("""
                Domain: \(error.domain)
                Code: \(error.code)
                Description: \(error.localizedDescription)
                Failure Reason: \(error.localizedFailureReason ?? "")
                Suggestions: \(error.localizedRecoverySuggestion ?? "")
                """)
        
    

View 加载 ViewModel 数据,leading 添加按钮能够添加和显示数据,但打开新视图的 trailing 不会更新视图。我必须终止应用才能获取新数据。

    NavigationView
        List 
            ForEach(gameList.gameCellViewModels)  gameList in
                CellView(gameCellViewModel: gameList)
            
        .navigationBarTitle("Games Played")
            .navigationBarItems(leading: Text("Add").onTapGesture 
                let arr:[Int] = [1,2,3]
                self.gameList.addNew(game: GameModel(game: arr))
                , trailing: NavigationLink(destination: ContentView())
                    Text("Play")
            )
    

播放查看示例

@State var test = ""
var body: some View 
    VStack()
        TextField("Enter value", text: $test)
            .keyboardType(.numberPad)
        
        Button(action: 
            var arr:[Int] = []
            arr.append(Int(self.test)!)
            self.gameList.addNew(game: GameModel(game: arr))
        ) 
            Text("Send")
        
    

【问题讨论】:

您能否在尾随中显示 ContentView(),因为它似乎无法正常工作。您只是提到它不显示数据,但我们对视图一无所知。 trailing: NavigationLink(destination: ContentView()) 【参考方案1】:

据我所知,问题似乎在这里:

List 
   // Add id: \.self in order to distinguish between items 
   ForEach(gameList.gameCellViewModels, id: \.self)  gameList in                    
      CellView(gameCellViewModel: gameList)                    
   

ForEach 需要一些东西来定位自己,以便知道哪些元素已经显示,哪些没有。

如果这没有解决问题。请将您提供的代码更新为Create a minimal, Reproducible Example

【讨论】:

我的模型中已经有可识别的了。我发现问题有所不同。我已经更新了问题。

以上是关于从不同视图添加新项目时,SwiftUI ObservedObject 不会更新的主要内容,如果未能解决你的问题,请参考以下文章

SwiftUI - 将数据传递到不同的视图

SwiftUI:在数组中更新值后视图没有改变

选择添加到 SwiftUI 列表的新项目

如何从 SwiftUI 的详细信息视图(编辑项目视图)中删除核心数据条目?

SwiftUI - 在按钮单击时添加一行多个文本字段/视图

在 SwiftUI 中将视图添加到层​​次结构时如何动画过渡