如何更新TextField值并在数组中更新其关联索引



我在更新通过for each循环显示的数组中的值时遇到问题。这些值显示在文本字段中。

有问题的代码

struct EditItemView: View {
let entity: RecipeEntity
@StateObject var viewModel = ViewModelEdit()
@State var imageToUpload: Data
@StateObject var vm = CoreDataRelationshipViewModel()
@Environment(.presentationMode) var presentationMode
@State var stepInfo: String = ""
@State var textFieldCount: Int = 1
@State var stepNumber: [Int]
@State var recipeName: String = ""
@State var recipeArray: [RecipeStepModel]
var body: some View {
//some code between here and the problem code
List {
ForEach(recipeArray, id: .id) { index in
HStack {
CustomTextField(item: index)
}
}.onDelete { (indexSet) in
recipeArray.remove(atOffsets: indexSet)
}

我正在使用的CustomTextField允许我将我的Identifiable模型传递到foreach中。这可以在上文中被引用为CustomTextField(item: index)

struct CustomTextField : View {
@State var item : RecipeStepModel
var body : some View {
Text(String(item.stepNumber) + ".")
TextField("", text: $item.stepName)
}

}

最后,这里是最后一个声明为@State var recipeArray: [RecipeStepModel]:的@State变量中引用的数组的模型

struct RecipeStepModel: Identifiable {
var id = UUID()
var stepName: String
var stepNumber: Int 

}

问题

如何更改foreach循环中的文本字段,并相应地更新其在@State var recipeArray: [RecipeStepModel]中的值?例如,我编辑For each循环中的第一个TextField——如何用它的新值更新数组中的索引0?

附加信息

前几天我发布了一个类似的问题。我能够让它在每个循环中使用.index。这里所问问题的版本是尝试使用MVVM重构我的代码。以前的问题和答案可以在这里找到-我希望这有帮助!

您需要遵循MVVM这样的体系结构。制作一个包含结构RecipeStepModel的模型,然后制作一个单独的ViewModel来添加和删除数组中的配方。您应该学习SwiftUI中的Combine框架,它用于从文本字段获取输入,然后将其存储在数组中。

查看Peter Freise的本教程https://github.com/peterfriese/MakeItSo/tree/firebase-combine/final/MakeItSo/MakeItSo以供参考。

我最终通过将视图模型中的@State var item: RecipeStepModel转换为@Binding var item: RecipeStepModel来解决问题

struct CustomTextField : View {
@Binding var item : RecipeStepModel
var body : some View {
Text(String(item.stepNumber) + ".")
TextField("", text: $item.stepName)
}

一旦进行了此更改,我就必须更改ForEach中的代码,以便将绑定传递给CustomTextField视图模型。此外,我不得不将ForEach(recipeArray, id: .id)更改为ForEach(recipeArray.indices, id: .self):

List {
ForEach(recipeArray.indices, id: .self) { index in
HStack {
CustomTextField(item: $recipeArray[index]) //<--change made here
}
}.onDelete { (indexSet) in
recipeArray.remove(atOffsets: indexSet)
}

我现在既可以成功地从列表中删除项目,也可以简单地通过更改相应的TextField 中的值来更新数组中的项目

最新更新