Swift:如何将单选组从多选改为单选并保留选中状态
解决单选按钮组(Radio Group)的多选问题并保留选中状态
核心思路
要实现单选功能,关键是每次选中某个选项时,将同一问题下的所有其他选项设为未选中状态,同时保留选中值的存储,确保视图切换后状态不丢失。
步骤1:修改ViewModel中的选中逻辑
替换原来的selectedRowTapped2函数,实现单选逻辑:
func selectedRowTapped2(selectedQuestion: AssessmentModel, selectedRow: AssessmentOption) { // 定位当前问题在数组中的索引 guard let questionIndex = radioDataPage1.firstIndex(where: { $0.id == selectedQuestion.id }) else { return } // 1. 将当前问题下所有选项设为未选中 for optionIndex in radioDataPage1[questionIndex].options.indices { radioDataPage1[questionIndex].options[optionIndex].isChecked = false } // 2. 定位选中的选项并设为已选中 if let selectedOptionIndex = radioDataPage1[questionIndex].options.firstIndex(where: { $0.id == selectedRow.id }) { radioDataPage1[questionIndex].options[selectedOptionIndex].isChecked = true // 更新选中值存储(单选场景下,values数组仅保留当前选中值) radioDataPage1[questionIndex].values = [selectedRow.value] } }
逻辑说明
- 原代码的
toggle()仅切换单个选项状态,导致多选;现在先统一重置所有选项,再激活选中项,确保同一问题下仅一个选项被选中。 - 使用
firstIndex(where:)通过UUID定位选项,比依赖selectedRow.value作为索引更可靠,避免选项顺序变动引发错误。
步骤2:优化模型结构(可选但推荐)
你的AssessmentModel中values: [Int]是数组类型,更适配多选场景。如果是单选,建议改为单个可选值,逻辑更清晰:
struct AssessmentModel: Identifiable { var id: Int var question: String var selectedValue: Int? // 替换原有的values数组 var options: [AssessmentOption] }
初始化数据时对应修改:
@Published var radioDataPage1: [AssessmentModel] = [ AssessmentModel(id: 0, question: CRContent.depQuestion1, selectedValue: nil, options: [ AssessmentOption(options: CRContent.notAtAllText, value: 0), AssessmentOption(options: CRContent.severalDaysText, value: 1), AssessmentOption(options: CRContent.moreThanHalfText, value: 2), AssessmentOption(options: CRContent.nearlyEverydayText, value: 3), ]), // 其他问题... ]
同时更新selectedRowTapped2中的存储逻辑:
// 替换原来的values赋值 radioDataPage1[questionIndex].selectedValue = selectedRow.value
步骤3:视图无需修改
你的视图代码已经可以根据isChecked状态正确显示单选图标,无需额外调整。如果需要在视图中获取选中值,直接从vm.radioDataPage1的selectedValue(或values.first)读取即可。
这样修改后,既实现了单选功能,又能在视图切换时保留选中状态,符合你的需求。
内容的提问来源于stack exchange,提问作者Duc Dang
相关产品推荐
相关产品推荐

