【问题标题】:Prevent array re-shuffle in SwiftUI防止 SwiftUI 中的数组重新洗牌
【发布时间】:2021-09-24 02:49:02
【问题描述】:

我一直在 SwiftUI 中创建一个问答应用程序,并一直在尝试为随机排列的答案创建一个数组。最初我将数组改组如下:

var answers = ["answerOne", "answerTwo", "answerThree", "answerfour"].shuffled

这个数组以ForEach 循环的形式显示在屏幕上,该循环在如下所示的列中提供了选项(可以选择的答案):

Question:
Answer One
Answer Two
Answer Three
Answer Four

(Check answer button)

虽然效果很好,但当按下检查答案按钮时,答案数组将再次随机排列为不同的顺序,如下所示,这是不可取的。

Question:
Answer Three
Answer One
Answer Two
Answer Four

(Next question button)

有没有一种方法可以让我只在按下“下一个问题按钮”而不是“检查答案按钮”时才对数组进行洗牌?

以下是我尝试作为解决方案的代码,但它似乎没有奏效,我非常感谢任何人的任何意见或想法!

Button(action: {
    if(oddEven % 2 == 0) {
        checkNextText = "Next"
        oddEven += 1
    } else {
        checkNextText = "Check"
        answers.shuffled()
        oddEven += 1
    }

注意:checkNextText 是屏幕底部按钮的文本,oddEven 是一个 Int 变量,用于确定按钮应该读取 check 还是 next。

最小复制代码:

import SwiftUI

struct ContentView: View {
    
    @State var oddEven = 0
    @State var checkNextText = "Check"
    
    var body: some View {

        var orderedAnswers = [                    
        "answerOne",
        "answerTwo",
        "answerThree",
        "answerFour"                    
        ].shuffled()

        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"
                oddEven += 1
            }
        }, label: {                        
            Text(checkNextText)
        })    
    }
}

【问题讨论】:

  • 您能否包含一个minimal reproducible example,以便他人可以复制并粘贴到 Xcode 中以查看您目前拥有的内容?
  • 嗨!没问题,我会在编辑中添加一个。
  • body 会在您的视图中的某些内容发生变化时刷新...所以由于var orderedAnswers = [body 内,它会意外地重新洗牌。把它移到外面。
  • 感谢@aheze 的回答。唯一的问题是我提供的代码是实际代码的一个非常精简的版本,将它移到体外需要大量的重构。有没有其他方法可以实现洗牌,而不必将数组移到体外?
  • @imjonu 不幸的是没有。通常你希望你的所有变量都在身体之外,否则你会遇到奇怪的副作用。

标签: swift swiftui


【解决方案1】:

正如其他人所建议的那样,惯用的方法是将数组存储在您的视图中,而不是作为body 属性中的局部变量,因为正如已经指出的那样,每次body 是调用(可能不止一次发生)。

但是,如果由于各种原因无法将代码提取到正文之外,另一种方法是使用仅设置一次的 @State 属性:

struct ContentView: View {
    @State orderedAnswers: [String]?

,仅当状态未设置时才进行计算:

var body: some View {
    var orderedAnswers = self.orderedAnswers ?? [                    
        "answerOne",
        "answerTwo",
        "answerThree",
        "answerFour"                    
        ].shuffled()

【讨论】:

    猜你喜欢
    • 2021-04-23
    • 1970-01-01
    • 2015-04-15
    • 2018-03-09
    • 2013-06-28
    • 1970-01-01
    • 1970-01-01
    • 2021-12-18
    相关资源
    最近更新 更多