code: with this code i am able to select each question multi check boxes but when it comes selecting radio button selection then i can able to select any one question options... if i select another question option then before question selection removes why? how to select each question options
struct SurveyQuestionsView: View {
@Environment(\.dismiss) var dismiss
@StateObject private var viewModel = SurveyViewModel()
@State var id: String = ""
@State private var selectedOption: Int? = nil
@State private var selectedOptions: Set<Int> = []
var body: some View {
ZStack {
VStack(alignment: .leading) {
Text("(*) Mandatory Questions")
.font(.calibriRegular(with: 15))
.foregroundStyle(.red)
.padding()
ScrollView{
ForEach(0..<viewModel.questionsArray.count, id: \.self) {i in
questionOptionsCell(question: viewModel.questionsArray[i])
Rectangle()
.frame(height: 3)
.foregroundColor(Color.hexF4F4FC)
}
}
Spacer()
}
}
.onAppear{
viewModel.fetchQuestionOptions(id: id) { status in
}
}
}
@ViewBuilder
func questionOptionsCell(question: QuestionSurvey) -> some View {
VStack(alignment: .leading) {
HStack {
Text(question.question ?? "N/A")
.font(.calibriRegular(with: 17))
.foregroundStyle(.green)
.padding(.leading, 10)
if question.isMultiSelect ?? false {
Text("*")
.foregroundColor(.red)
}
}
ForEach(question.options ?? [], id: \.optID) { option in
HStack {
if question.isMultiSelect ?? false {
Image(systemName: selectedOptions.contains(option.optID!) ? "checkmark.square" : "square")
.onTapGesture {
if selectedOptions.contains(option.optID!) {
selectedOptions.remove(option.optID!)
} else {
selectedOptions.insert(option.optID!)
}
}
} else {
Image(systemName: (selectedOption == option.optID ? "largecircle.fill.circle" : "circle"))
.onTapGesture {
if selectedOption != option.optID {
selectedOption = option.optID
}
}
}
Text(option.option ?? "Option")
.onTapGesture {
if question.isMultiSelect ?? false {
if selectedOptions.contains(option.optID!) {
selectedOptions.remove(option.optID!)
} else {
selectedOptions.insert(option.optID!)
print("selectedOption.... \(selectedOptions)")
}
} else {
selectedOption = option.optID
print("selectedOption.... \(selectedOption)")
}
}
Spacer()
}
.padding(.vertical, 5)
.padding(.leading, 15)
}
}
}
}
o/p
edit: this is QuestionSurvey model
struct QuestionSurvey: Codable {
let queID: Int?
let question: String?
let isMultiSelect, isAnsMandatory: Bool?
let response: Int?
var options: [Option]?
}
tried like this still same issue
else {
Image(systemName: (selectedOption == option.optID ? "largecircle.fill.circle" : "circle"))
.onTapGesture {
selectedSingleOptions[question.queID ?? 0] = option.optID ?? 0
}
}
If I understand correctly, the issue is that when you select an answer from the second question with radio buttons, the answer from the first question with radio buttons is de-selected.
I was able to reproduce this by running your code (after improvising all the missing parts). The problem is happening because the id of the selected answer is stored in selectedOption
, which effectively means, you only have one radio button group.
To fix, you need to have one variable per radio button group. You could do this by using a dictionary, keyed by question id.
Assuming that each question has an Int
id:
@State private var selectedSingleOptions = [Int: Int]()
if question.isMultiSelect ?? false {
// ...
} else {
Image(systemName: (selectedSingleOptions[question.id] == option.optID ? "largecircle.fill.circle" : "circle"))
.onTapGesture {
selectedSingleOptions[question.id] = option.optID ?? 0
}
}