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

SwiftUI实现选择题仅加载新题目时打乱答题选项

解决Trivia API选项重复打乱的问题

你当前的问题在于每次用户选择答案后,视图状态变化触发重绘,而ForEach里直接调用shuffleAnswers()会导致每次重绘都重新打乱选项。要实现仅加载新题时打乱选项,需要把打乱后的选项存储为状态变量,只在切换题目时更新它。

修改步骤:

  1. 添加状态变量存储当前题目的打乱选项
    在你的View结构体中添加一个@State变量,用来保存当前题目的已打乱选项:
@State private var currentShuffledAnswers: [String] = []
  1. 重构选项打乱逻辑,仅在加载新题时执行
    创建一个专门加载并打乱当前题目选项的方法,替换原来的shuffleAnswers():
func loadCurrentQuestionAnswers() {
    guard !api.QnAData.isEmpty, currentQuestionIndex < api.QnAData.count else {
        currentShuffledAnswers = []
        return
    }
    let currentQuestion = api.QnAData[currentQuestionIndex]
    var answers = currentQuestion.incorrectAnswers
    answers.append(currentQuestion.correctAnswer)
    // 解码并打乱选项,结果存入状态变量
    currentShuffledAnswers = answers.compactMap { $0.removingPercentEncoding }.shuffled()
}
  1. 在合适时机触发选项加载
  • 视图首次出现时加载初始题目选项:
.onAppear {
    loadCurrentQuestionAnswers()
}
  • 点击「Next」按钮切换题目后,重新加载新题的打乱选项:
Button("Next") {
    currentQuestionIndex += 1
    // 重置答题状态
    answerSelected = nil
    hasUserAnswered = false
    // 加载新题的打乱选项
    loadCurrentQuestionAnswers()
}
.disabled(!hasUserAnswered) // 保持原有的未答题不可点击逻辑
  1. 修改ForEach遍历状态变量
    把原来ForEach(shuffleAnswers(), id: \.self)改成遍历存储好的currentShuffledAnswers,避免每次重绘都重新打乱:
if !api.QnAData.isEmpty {
    ForEach(currentShuffledAnswers, id: \.self) { shuffledAnswer in
        Button(action: {
            guard answerSelected == nil else { return }
            
            let decodedAnswer = shuffledAnswer.removingPercentEncoding ?? shuffledAnswer
            answerSelected = decodedAnswer
            hasUserAnswered = true
            
            // 判断答案是否正确并更新得分
            let correctAnswer = api.QnAData[currentQuestionIndex].correctAnswer.removingPercentEncoding ?? api.QnAData[currentQuestionIndex].correctAnswer
            if decodedAnswer == correctAnswer {
                score += 1
                print("答对了,当前得分:\(score)")
            } else {
                print("答错了,当前得分:\(score)")
            }
        }) {
            Text(shuffledAnswer)
            // 保留你原有的按钮样式代码
        }
    }
}

为什么原来的写法会出问题?

SwiftUI是状态驱动的视图框架,当answerSelected、hasUserAnswered这类状态变量变化时,整个View会重新渲染。原来在ForEach里直接调用shuffleAnswers(),相当于每次渲染都执行一次打乱逻辑,所以用户选完答案后状态变化触发重绘,选项就被重新打乱了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 21:08:42