You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 00:54:03