I have a view model which handles the loading of new data once the app launches and when a new item is added. I have an issue when it comes to showing new items when are added from a new view, for example, a sheet
or even a NavigationLink
.
View Model
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 to load the ViewModel data, leading
add button is able to add and show data but the trailing
which opens a new View does not update the view. I have to kill the app to get the new data.
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")
})
}
Play View sample
@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")
}
}
}
To what I can see the issue seems to be here:
List {
// Add id: \.self in order to distinguish between items
ForEach(gameList.gameCellViewModels, id: \.self) { gameList in
CellView(gameCellViewModel: gameList)
}
}
ForEach needs something to orientate itself on in order to know what elements are already displayed and which are not.
If this did not solve the trick. Please update the code you provided to Create a minimal, Reproducible Example
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.