SwiftUI中如何实现类/模型的多实例?TextField输入内容丢失问题求助
问题分析与解决方案
你的问题根源在于多个按钮共用同一个showNew状态,且每个按钮都附加了独立的.sheet修饰符,这会导致SwiftUI的状态管理混乱,进而在操作过程中意外重建CreateNewCardViewModel,使得输入的文本被清空。另外,每次弹出sheet时都直接创建新的viewModel,也会让数据的稳定性得不到保障。
下面是具体的修复步骤:
1. 修正主视图的Sheet绑定方式
把.sheet从每个Button的修饰符移到主视图的根容器上,同时使用sheet(item:)替代isPresented,这样可以精准控制每次弹出对应的viewModel,避免状态冲突。
首先,让Int符合Identifiable协议,适配sheet(item:)的要求:
extension Int: Identifiable { public var id: Int { self } }
然后修改主视图的实现:
struct MainView: View { // 存储当前选中的卡片ID,nil表示不显示sheet @State var selectedId: Int? var body: some View { VStack { // 用VStack作为根容器,统一挂载sheet ForEach(0...10, id: \.self) { index in Button(action: { // 点击按钮时,设置选中的ID selectedId = index }, label: { Text("Create Card \(index)") }) } } // 使用sheet(item:)绑定选中的ID,只有当selectedId不为nil时才弹出sheet .sheet(item: $selectedId) { id in CreateNewCard(viewModel: CreateNewCardViewModel(id: id)) } } }
2. 确保ViewModel的状态稳定
现在每次弹出sheet时,CreateNewCardViewModel只会基于当前选中的id创建一次,不会因为多个按钮的sheet绑定冲突而意外重建。这样你在TextField中输入内容时,@Published var definition会正确保存输入值,按下键盘返回键(收起键盘)也不会清空文本。
额外优化(可选)
如果希望sheet关闭后保留输入的内容(比如后续编辑),你可以在主视图中维护一个viewModels数组,提前创建好所有的viewModel,而不是每次弹出时新建:
struct MainView: View { @State var selectedId: Int? // 提前创建所有viewModel,持久化存储输入数据 @State var viewModels: [CreateNewCardViewModel] = (0...10).map { CreateNewCardViewModel(id: $0) } var body: some View { VStack { ForEach(0...10, id: \.self) { index in Button(action: { selectedId = index }, label: { Text("Edit Card \(index)") }) } } .sheet(item: $selectedId) { id in // 传递已有的viewModel,而不是新建 CreateNewCard(viewModel: viewModels[id]) } } }
这样即使sheet关闭再打开,之前输入的内容也会被保留下来。
内容的提问来源于stack exchange,提问作者Erik
相关产品推荐
相关产品推荐

