SwiftUI分值按钮异常:点击按钮却修改其他分值的问题求助
问题分析
你遇到的核心问题是所有按钮共享同一个showingAlert布尔状态变量。当任意按钮点击后将showingAlert设为true时,所有绑定该状态的.alert修饰符都会被触发,但SwiftUI无法区分当前弹窗是由哪个按钮触发的,最终会执行最后定义的弹窗动作(或因视图更新逻辑出现随机匹配其他分值的情况),这就导致了分值与按钮不对应的问题。
解决方案
改用可选类型的状态变量存储当前选中的分值,通过这个变量控制弹窗显示,并在弹窗中根据选中的分值执行分数增减操作,以此精准关联按钮与对应分值逻辑。
修改后的完整代码示例:
import SwiftUI // 补充完整CurrentGameStatus定义 class CurrentGameStatus: ObservableObject { @Published var score = 0 } struct ScoreHeader: View { @ObservedObject var gameStatus: CurrentGameStatus var body: some View { Text("Score: \(gameStatus.score)") .font(.title) } } struct QuestionValueButtonStyle: ButtonStyle { func makeBody(configuration: Configuration) -> some View { configuration.label .padding() .background(.blue) .foregroundColor(.white) .cornerRadius(8) } } struct ContentView: View { // 用可选Int存储当前选中的分值,nil表示不显示弹窗 @State private var selectedScore: Int? // 当前视图创建的ObservableObject推荐用@StateObject管理生命周期 @StateObject var gameStatus = CurrentGameStatus() var body: some View { NavigationStack { HStack { VStack(spacing: 16) { ScoreHeader(gameStatus: gameStatus) Button(action: { gameStatus.score = 0 }) { Text("Reset Score") } Button(action: { selectedScore = 200 }) { Text("200") } .buttonStyle(QuestionValueButtonStyle()) Button(action: { selectedScore = 400 }) { Text("400") } .buttonStyle(QuestionValueButtonStyle()) Button(action: { selectedScore = 600 }) { Text("600") } .buttonStyle(QuestionValueButtonStyle()) Button(action: { selectedScore = 800 }) { Text("800") } .buttonStyle(QuestionValueButtonStyle()) } // 统一绑定弹窗状态,仅需一个.alert修饰符 .alert("Did you get the question right?", isPresented: .constant(selectedScore != nil)) { Button("Yes") { if let score = selectedScore { gameStatus.score += score } selectedScore = nil // 关闭弹窗后重置状态 } Button("No") { if let score = selectedScore { gameStatus.score -= score } selectedScore = nil } } } .padding() } } }
关键修改点
- 替换
showingAlert为selectedScore: Int?,通过存储具体分值关联按钮与弹窗逻辑 - 每个按钮点击时设置对应分值到
selectedScore,而非简单切换布尔值 - 仅保留一个
.alert修饰符,通过selectedScore != nil判断弹窗显示状态,内部根据选中分值执行分数操作 - 将
@ObservedObject改为@StateObject,符合SwiftUI对本地创建的ObservableObject的生命周期管理规范
内容的提问来源于stack exchange,提问作者Griffin-Reding
相关产品推荐
相关产品推荐

