I have created a custom view which contains a textview, a textfield and a picker with three items.
Now this is added by iterating an array using a foreach loop. These can be more than one based on the response from the server. Now I wish to get the data back from the textfield and the textfield. I tried to use Binding in the forEach loop but it is now receiving any update done in these views.
Thanks for showing the refactored code. It compiled fine.
I needed to add enableButtonBool = true
, but it was a great help to guess what you want to do.
(I still do not understand some parts of the code, but it may be better to show what I guessed.)
I may be mistaking something, but you may want to do something like this:
import SwiftUI
struct ChecklistModel: Codable, Hashable {
var description, remarks, status: String?
}
struct CheckListCard: View {
@Binding var checkListData : ChecklistModel
@State var statusList: [String] = []
@Binding var enableButtonBool: Bool
var body: some View {
let currentStatus = Binding<String>(
get: {checkListData.status ?? ""},
set: {checkListData.status = $0})
let currentRemark = Binding<String>(
get: {checkListData.remarks ?? ""},
set: {checkListData.remarks = $0})
VStack{
Text("Description").padding()
.onAppear(){
addData()
}
if let description = checkListData.description {
Text(description)
.padding()
}
Text("Status").padding()
if checkListData.status != nil {
Picker("Status", selection: currentStatus) {
ForEach(statusList, id: \.self){ status in
Text(status)
}
}.pickerStyle(SegmentedPickerStyle())
.padding()
.disabled(!enableButtonBool)
}
Text("Remarks")
if checkListData.remarks != nil {
TextField("Remarks", text: currentRemark)
.disabled(!enableButtonBool)
.padding()
.background(Color(.white))
.cornerRadius(8)
.accentColor(.gray)
} else {
TextField("Remarks", text: currentRemark)
.disabled(!enableButtonBool)
.padding()
.background(Color(.white))
.cornerRadius(8)
}
}
.padding()
.background(Color("light_gray"))
.foregroundColor(.black)
.cornerRadius(8)
.shadow(radius: 10)
.padding()
}
func addData() {
statusList.append("Yes")
statusList.append("No")
statusList.append("NA")
if let status = checkListData.status {
statusList.append(status) //<- Why this is needed?
}
}
}
struct CheckListSheet: View {
@State var taskId: Int
@State var checklistResponse: [ChecklistModel] = [ChecklistModel()]
@State var enableButtonBool: Bool = false
@State var statusList: [String] = []
var body: some View {
Text("Checklist Items")
.padding()
.font(.title)
ScrollView {
ForEach(checklistResponse.indices, id:\.self) { index in
CheckListCard(checkListData: $checklistResponse[index],
enableButtonBool: $enableButtonBool)
}
if enableButtonBool {
Button("Update") {
updateCheckList()
}
}
}
.onAppear(){
getChecklists()
}
}
func updateCheckList() {
print("this is the checklistresponse \(checklistResponse)")
}
func getChecklists() {
checklistResponse = [
ChecklistModel(description: "ist item", remarks: nil, status: "Yes"),
ChecklistModel(description: "2nd item", remarks: "Fine", status: "no")
]
enableButtonBool = true
}
}