首页 > 解决方案 > 将 ForEach 与一个绑定数组一起使用 (SwiftUI)

问题描述

我的目标是从 JSON 动态生成表单。除了生成 FormField 视图(基于 TextField)并绑定到动态生成的视图模型列表之外,我已经将所有内容放在一起。

如果我将 FormField 视图换成普通的 Text 视图,它可以正常工作(见截图):

ForEach(viewModel.viewModels) { vm in
    Text(vm.placeholder)
}

为了

ForEach(viewModel.viewModels) { vm in
     FormField(viewModel: $vm)
}

我试图创建一个 @State var的viewModels属性,但它失去了它的可编码性。ConfigurableFormViewModelJSON > Binding<[FormFieldViewModel] 自然是不行的。

这是我的代码的要点:

来自 JSON 但使用 <code>Text</code> 的表单屏幕截图

标签: swiftswiftui

解决方案


您可以尝试的第一件事是:

ForEach(0 ..< numberOfItems) { index in
   HStack {
     TextField("PlaceHolder", text: Binding(
       get: { return items[index] },
       set: { (newValue) in return self.items[index] = newValue}
     ))
   }
}

前一种方法的问题是,如果numberOfItems某个按钮的动作是动态的并且可能会发生变化,那么它就不会起作用,并且会抛出以下错误:ForEach<Range<Int>, Int, HStack<TextField<Text>>> count (3) != its initial count (0). 'ForEach(_:content:)' should only be used for *constant* data. Instead conform data to 'Identifiable' or use 'ForEach(_:id:content:)' and provide an explicit 'id'!

如果你有这个用例,你可以做这样的事情,即使项目在 SwiftView 的生命周期中增加或减少,它也会起作用:

ForEach(items.indices, id:\.self ){ index in
   HStack {
     TextField("PlaceHolder", text: Binding(
       get: { return items[index] },
       set: { (newValue) in return self.items[index] = newValue}
     ))
   }
}

推荐阅读