SwiftUI返回主界面后“购物清单”列表未清空问题求助
问题
开发的购物清单应用功能基本正常,但保存填写完成的新购物清单并返回主界面后,新建清单页面的所有字段均已清空,唯独“Shopping List”列表的内容仍保留。尝试过将item和itemPrice文本框设置为空字符串,但问题仍未解决。
应用代码
import Foundation struct ItemToAdd: Identifiable { var id = UUID() var itemName: String var itemPrice: String } import Foundation struct NewList: Identifiable { var id = UUID() var storeName: String var budget: Float var item: String var itemPrice: String } import Foundation class HomePageItem: Observable, ObservableObject { @Published var items: [NewList] = [] @Published var itemsToAdd: [ItemToAdd] = [] var totalMoneySpent: Float { itemsToAdd.reduce(0) { $0 + $1.itemPrice.floatValue } } } extension String { var floatValue: Float { return (self as NSString).floatValue } } import SwiftUI struct CreateNewListing: View { @EnvironmentObject var settings: HomePageItem @State var storeName: String @State var budget: Float @State var adjustedBudget: Float @State var itemName: String @State var itemPrice: String @State var newBudget: Float @State var boolValue = false var body: some View { NavigationStack { Form { Section(header: Text("Store Name")) { TextField("e.g, Trader Joe's", text: $storeName) } Section(header: Text("Budget")) { TextField("Enter your budget", value: $budget, format: .number) } Section(header: Text("Enter Item and Price")) { List { HStack { TextField("Item", text: $itemName) TextField("Price", text: $itemPrice) } Button { self.addToList() print(settings.totalMoneySpent) }label: { Text("Add Item") } } } Section(header: Text("Shopping List")) { List { ForEach(settings.itemsToAdd) { item in HStack { Text(item.itemName) Text(item.itemPrice) } } Text("Available Money Left: \(budget - self.settings.totalMoneySpent, specifier: "%.2f")") .foregroundColor(budget - self.settings.totalMoneySpent >= 0 ? Color.green: Color.red) } } } .navigationTitle("Create New List") .toolbar { Button { settings.items.append(NewList(storeName: storeName, budget: budget, item: itemName, itemPrice: itemPrice)) print(settings.items) }label: { Text("Save") } } } .environmentObject(settings) } func addToList() { guard !itemName.trimmingCharacters(in: .whitespaces).isEmpty else { return } guard !itemPrice.trimmingCharacters(in: .whitespaces).isEmpty else { return } boolValue = false let newItem = ItemToAdd(itemName: itemName, itemPrice: itemPrice) for item in settings.itemsToAdd{ if (item.itemName.contains(itemName) && (item.itemPrice.contains(itemPrice))){ boolValue = true } } if boolValue == false{ settings.itemsToAdd.append(newItem) itemName = "" itemPrice = "" } } } extension String { var floatValue1: Float { return (self as NSString).floatValue } } #Preview { CreateNewListing(storeName: "", budget: 0.00, adjustedBudget: 0.00, itemName: "", itemPrice: "", newBudget: 0.00) .environmentObject(HomePageItem()) } import SwiftUI struct ContentView: View { @StateObject var settings: HomePageItem var body: some View { NavigationStack { VStack { List { ForEach(settings.items) { item in HStack { Text(item.storeName) .multilineTextAlignment(.leading) Spacer() HStack { if(item.budget - settings.totalMoneySpent >= 0){ Text("You saved \(item.budget - settings.totalMoneySpent, specifier: "%.2f")") } } } } } } .toolbar { NavigationLink { CreateNewListing(storeName: "", budget: 0.00,adjustedBudget: 0.00, itemName: "", itemPrice: "", newBudget: 0.00) } label: { Image(systemName: "plus") .foregroundColor(.orange) .font(.title3) } } .navigationTitle("My Shopping Lists") } .environmentObject(settings) } } #Preview { ContentView(settings: HomePageItem()) }
解决方案
核心原因
HomePageItem中的itemsToAdd是全局共享的状态变量,保存清单后没有清空,且每次进入新建页面时也未重置,导致旧的购物项一直保留。
修改步骤
修正
HomePageItem协议冗余
移除多余的Observable协议,只保留ObservableObject:class HomePageItem: ObservableObject { @Published var items: [NewList] = [] @Published var itemsToAdd: [ItemToAdd] = [] var totalMoneySpent: Float { itemsToAdd.reduce(0) { $0 + $1.itemPrice.floatValue } } }保存后清空购物项列表
在CreateNewListing的保存按钮中添加清空逻辑:.toolbar { Button { settings.items.append(NewList(storeName: storeName, budget: budget, item: itemName, itemPrice: itemPrice)) // 保存完成后清空购物项 settings.itemsToAdd.removeAll() print(settings.items) }label: { Text("Save") } }进入页面时重置购物项列表
给NavigationStack添加onAppear修饰符,确保每次进入新建页面都是干净状态:NavigationStack { // 原Form内容 } .onAppear { settings.itemsToAdd.removeAll() } .environmentObject(settings)移除无用状态变量
删除CreateNewListing中未使用的adjustedBudget、newBudget变量,简化代码:struct CreateNewListing: View { @EnvironmentObject var settings: HomePageItem @State var storeName: String @State var budget: Float @State var itemName: String @State var itemPrice: String @State var boolValue = false // 剩余代码不变 }同步修改预览和跳转参数
更新预览代码:#Preview { CreateNewListing(storeName: "", budget: 0.00, itemName: "", itemPrice: "") .environmentObject(HomePageItem()) }更新
ContentView中的跳转参数:NavigationLink { CreateNewListing(storeName: "", budget: 0.00, itemName: "", itemPrice: "") } label: { Image(systemName: "plus") .foregroundColor(.orange) .font(.title3) }
额外优化建议
NewList结构体中的item和itemPrice字段无实际意义,建议修改为关联完整购物项列表:
保存时同步传入购物项列表:struct NewList: Identifiable { var id = UUID() var storeName: String var budget: Float var items: [ItemToAdd] }settings.items.append(NewList(storeName: storeName, budget: budget, items: settings.itemsToAdd))
内容的提问来源于stack exchange,提问作者Dan Fitzgerald
相关产品推荐
相关产品推荐

