[英]Working with Dynamic Form and field States in SwiftUI
我有點不知道如何使用動態 forms 來處理狀態。我肯定不能為每個字段創建狀態,因為我不知道有多少字段,因為這些 Forms 基本上是從 JSON 響應構建的。
這基本上是我現在所擁有的,也是我想要改變的。 最初,當 forms 不是動態構建時,我為每個字段創建了一個 state,現在我不知道如何繼續。
我考慮過使用 Dictionary,但我不確定這個解決方案有多好。
@State var textfieldText: String = ""
@State var SKU: String = ""
@State private var showScanner: Bool = false
var currentForm: FormModel
@State var RecordDate: Date = Date.now
@State var Formresponse: [String: Any] = [:]//This one is set to any because the value can vary from a string to [] to even a whole object
我如何呈現我的表格:
ForEach(currentForm.item, id:\.idf) { it in
if (!it.questionItem.hidden)
{
switch it.questionItem.questionType {
case .dateQuestion :
DateField(title: it.title, currentDate: $RecordDate)
case .choiceQuestion:
Text("choice question")
case .scannerQuestion:
ScannerField(title: it.title, SKU: $SKU, showScanner: $showScanner)
case .textQuestion:
TextQuestionField(title: it.title, email: currentForm.owner, text: $textfieldText)
}
}
}
我最終將不得不以字典的形式提交這些數據,這就是為什么我考慮使用 Dict ["fieldID":"FieldInput","fieldId2":"FieldInput2"..]
為問題類型定義枚舉:
enum FormItemType {
case dataQuestion
case choiceQuestion
case scannerQuestion
case textQuestion
}
為問題類型定義項目 model:
struct FormItemModel : Identifiable {
var type : FormItemType
var itemObject : Any
var userInput : String?
let id : UUID
}
定義表單視圖 model:
final class FormModel : ObservableObject {
@Published var items : [FormItemModel] = []
}
和觀點:
struct ContentView: View {
@ObservedObject var formViewModel: FormModel
@Binding var currentInput : String
var body: some View {
List {
ForEach(formViewModel.items, id: \.id, content: { item in
switch item.type {
case .dataQuestion:
Text(item.itemObject as? String ?? "")
case .scannerQuestion:
Text("\(item.itemObject as? Int ?? 0 )")
case .choiceQuestion:
if let dic = item.itemObject as? [String:String]{
VStack{
Text(dic["Q"]!)
Text(dic["A1"]!)
Text(dic["A2"]!)
Text(dic["A3"]!)
}
}
case .textQuestion:
VStack{
Text(item.itemObject as? String ?? "")
TextEditor(text: $currentInput)
}
}
})//ForEach
}//List
}
}//View
這是表單的虛擬值:
items = [FormItemModel(type: .textQuestion, itemObject: "Tell Me About Yourself...", id: UUID()),
FormItemModel(type: .choiceQuestion,
itemObject: ["Q":"How much is 1+1?", "A1":"1", "A2":"2", "A3":"3"],
id: UUID()),
FormItemModel(type: .scannerQuestion, itemObject: 1110111011, id: UUID())
]
我認為您只需要一個State
用於formResponse
。 您可以將其作為Binding
傳遞給每個輸入字段視圖,並且在該視圖中您可以創建自定義Binding
以獲取和設置formResponse
的答案。 是這樣的:
struct FormFieldInputView: View {
@Binding var formResponse: [String: Any]
let field: String
var body: some View {
TextField(field, text: Binding(
get: {
formResponse[field] as? String ?? ""
},
set: { newValue in
formResponse[field] = newValue
})
)
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.