SwiftUI实现3个按钮同一时间仅可一个处于选中状态问题求教
解决方案
核心思路是替换原有的3个独立Bool状态变量,改用单个枚举类型的状态存储当前选中项,天然实现单选互斥逻辑,同时能避免你原有代码里的积分计算、状态修改笔误问题。
步骤1:定义选项枚举
首先创建一个枚举统一管理三个按钮的选项、对应积分值,避免硬编码:
enum SelectionOption: String, CaseIterable { case yes = "Yes" case no = "No" case sometimes = "Sometimes" // 绑定每个选项对应的积分值 var point: Int { switch self { case .yes: return 5 case .no: return 3 case .sometimes: return 1 } } }
步骤2:替换状态变量
把你原来声明的ButtonYes、ButtonNo、ButtonSometimes三个@State Bool变量删掉,替换成单个可选类型的选中状态:
// 存储当前选中的选项,nil表示无选中 @State private var selectedOption: SelectionOption? // 你原有声明的Xcode、Ycode、ShowButton状态保留即可
步骤3:重写按钮点击与样式逻辑
三个按钮的逻辑完全统一,只需要替换对应枚举值即可,这里以Yes按钮为例:
Button("Yes") { ShowButton.toggle() // 先扣减旧选中项的积分 if let oldOption = selectedOption { Xcode -= oldOption.point Ycode -= oldOption.point } // 切换选中状态:如果当前是选中状态就取消,否则设为当前选项并加积分 if selectedOption == .yes { selectedOption = nil } else { selectedOption = .yes Xcode += SelectionOption.yes.point Ycode += SelectionOption.yes.point } } .frame(width: 50, height: 50, alignment: .center) .foregroundColor(.white) .padding() // 背景色判断逻辑替换为判断当前选项是否是选中项 .background(selectedOption == .yes ? Color(red: 0.272, green: 0.471, blue: 0.262) : Color(red: 0.493, green: 0.184, blue: 0.487)) .cornerRadius(20) .shadow(color: .black, radius: 10, x: 10, y: 10)
No和Sometimes按钮只需要把上面代码里所有的.yes替换为.no、.sometimes即可,不需要修改其他逻辑。
效果说明
该方案实现后:
- 任意时间最多只有一个按钮处于选中状态,点击新按钮会自动取消旧按钮的选中状态,同时自动完成旧选项积分扣减、新选项积分增加
- 避免了你原有代码里的笔误问题(比如No按钮的else分支错误修改了ButtonYes的状态)
- 后续如果要新增选项,只需要在枚举里加case即可,不需要新增状态变量
内容的提问来源于stack exchange,提问作者Curiousnoes
相关产品推荐
相关产品推荐

