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

SwiftUI选择题应用QuizBrain状态更新后界面未刷新问题求助

问题解决:SwiftUI视图未随QuizBrain状态更新而刷新

问题核心是SwiftUI无法感知到QuizBrain的状态变化——你的QuizBrain是结构体且用了全局变量,修改numQuestion时视图完全不知道数据已更新,自然不会刷新。以下是具体修复方案:


第一步:重构QuizBrain为可观察对象

把QuizBrain从结构体改为类,遵循ObservableObject协议,并用@Published标记需要触发视图更新的属性:

import Foundation
import SwiftUI

// 补充你缺失的Question结构体(加Identifiable方便后续ForEach使用)
struct Question: Identifiable {
    let id = UUID()
    let text: String
    let ans: [String]
    let imageName: String
}

class QuizBrain: ObservableObject {
    let questions = [
        Question(
            text: "What is the capital of the UK?", ans: ["London", "Paris", "Berlin", "Madrid"],
            imageName: "britain"),
        Question(
            text: "What is the capital of France?", ans: ["Paris", "London", "Berlin", "Madrid"],
            imageName: "france"),
        Question(
            text: "What is the capital of Spain?", ans: ["Madrid", "Paris", "Berlin", "London"],
            imageName: "spain"),
        Question(
            text: "What is the capital of Germany?", ans: ["Berlin", "Paris", "London", "Madrid"],
            imageName: "germany"),
    ]
    
    // 用@Published标记,变化时自动通知视图刷新
    @Published var numQuestion = 0
    @Published var score = 0

    func checkAns(userAnswer: String) {
        if userAnswer == questions[numQuestion].ans[0] {
            score += 1
            print("Correct")
        }

        // 修正下标越界问题:原判断会导致numQuestion超出数组范围
        if numQuestion < questions.count - 1 {
            numQuestion += 1
            print(numQuestion)
        } else {
            // 重置到第一题
            numQuestion = 0
        }
    }
}

第二步:在ContentView中使用状态对象

移除全局变量,用@StateObject在视图内部持有QuizBrain实例,让SwiftUI监测其状态变化:

import SwiftUI

struct ContentView: View {
    // @StateObject负责在视图生命周期内持久化实例并监测变化
    @StateObject private var brainQuiz = QuizBrain()
    
    var body: some View {
        VStack {
            // 用计算属性简化当前题目的访问
            Text(brainQuiz.currentQuestion.text)
            Image(brainQuiz.currentQuestion.imageName)
            
            Spacer()
            
            VStack {
                ForEach(brainQuiz.currentQuestion.ans, id: \.self) { title in
                    Button(action: {
                        brainQuiz.checkAns(userAnswer: title)
                    }) {
                        Text(title)
                            .font(.title2)
                            .padding()
                            .frame(maxWidth: .infinity)
                            .background(Color.blue)
                            .foregroundColor(.white)
                            .cornerRadius(10)
                    }
                }
            }
            .padding()
        }
    }
}

// 给QuizBrain加计算属性,简化视图代码
extension QuizBrain {
    var currentQuestion: Question {
        questions[numQuestion]
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

关键改动说明

  1. ObservableObject + @Published:让SwiftUI能感知numQuestion和score的变化,自动触发视图刷新。
  2. @StateObject:确保QuizBrain实例在视图生命周期内不被销毁,同时持续监测状态变化。
  3. 修正下标越界:原判断逻辑会导致numQuestion超出数组下标范围,现在的判断确保最后一题后正确重置到第一题。
  4. 计算属性currentQuestion:简化视图中的代码,避免重复写questions[numQuestion]。

内容的提问来源于stack exchange,提问作者Emma Hook

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 08:17:46