SwiftUI问答应用如何仅在切换下一题时打乱答案数组,避免校验时重排
问题原因
你遇到的数组反复打乱的核心原因是orderedAnswers被定义在body计算属性内部。只要View的任意@State属性发生改变(比如点击按钮修改了oddEven和checkNextText),就会触发View重绘,body会重新执行一遍,shuffled()方法就会被再次调用生成新的乱序数组。
解决方案
把乱序后的答案数组也声明为@State属性,仅在点击下一题的时候主动调用打乱逻辑即可,修改后的完整代码如下:
import SwiftUI struct ContentView: View { @State var oddEven = 0 @State var checkNextText = "Check" // 把答案数组声明为@State,初始加载时仅打乱一次 @State var orderedAnswers = [ "answerOne", "answerTwo", "answerThree", "answerFour" ].shuffled() // 存储原始的固定选项池,切换题目时用来生成新的乱序数组 let originalAnswers = [ "answerOne", "answerTwo", "answerThree", "answerFour" ] var body: some View { VStack(spacing: 16) { Text("Question One") ForEach(0..<4) { number in Button(action: {}, label: { Text(orderedAnswers[number]) }) } Button(action: { if oddEven % 2 == 0 { // 点击校验答案分支:仅修改按钮状态,不修改答案数组 checkNextText = "Next" oddEven += 1 } else { // 点击下一题分支:重新打乱答案数组后更新 checkNextText = "Check" orderedAnswers = originalAnswers.shuffled() oddEven += 1 } }, label: { Text(checkNextText) }) } .padding() } }
逻辑说明
- 把答案数组升级为
@State属性后,它的存储会被SwiftUI托管,只要你不主动修改它,View重绘时它的值不会发生变化 - 仅在点击下一题的分支里,主动给
orderedAnswers赋值为原始数组打乱后的新结果,就可以实现只有切换题目时才打乱选项的需求 - 如果后续要支持多道题目,可以把题目内容、正确答案、选项池都放到单独的数据模型里,切换题目的时候从对应题目模型取选项再打乱即可。
内容的提问来源于stack exchange,提问作者imjonu
相关产品推荐
相关产品推荐

