在 swiftui 中列表单选按钮选择中面临问题

问题描述 投票:0回答:1

代码:使用此代码,我可以选择每个问题的多个复选框,但是当选择单选按钮选择时,我可以选择任何一个问题选项...如果我选择另一个问题选项,则在问题选择之前删除为什么?如何选择每个问题选项

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

enter image description here

swift list swiftui foreach radio-button
1个回答
0
投票

如果我理解正确,问题是当您使用单选按钮从第二个问题中选择答案时,使用单选按钮的第一个问题的答案将被取消选择。

我能够通过运行您的代码来重现这一点(在临时修改所有缺失的部分之后)。发生问题是因为所选答案的 id 存储在

selectedOption
中,这实际上意味着,您只有一个单选按钮组。

要修复此问题,每个单选按钮组需要一个变量。您可以使用字典来完成此操作,并以问题 id 为键。

假设每个问题都有一个

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
        }
}

© www.soinside.com 2019 - 2024. All rights reserved.