swift 逻辑问题-内容两次刷新

j8ag8udp  于 2023-02-28  发布在  Swift
关注(0)|答案(1)|浏览(132)

通过SwiftUI的100天工作,我已经完成了里程碑:项目4-6(参考:https://www.hackingwithswift.com/100/swiftui/35),它似乎工作正常,除了一个逻辑错误,我显然是无意中创建的,这导致了问题的两次刷新,一次是在提供答案后,另一次是在点击警报窗口上的继续按钮后。如果您能帮助我了解我在这个特定问题上做错了什么,我将非常有帮助。
预先感谢你的帮助。
弹药。

import SwiftUI

struct ContentView: View {
    
    @State private var multiplier: Int = 1
    var numberOfQuestions = [5, 10, 12]
    @State private var chosenNumberOfQuestions = 0
    @State private var tableScale = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12].shuffled()
    @State private var counter = 1
    @State private var score = 0
    @State private var scoreTitle = ""
    @State private var showingScore = false
    @State private var finalMessage = ""
    @State private var showingFinalMessage = false
    
    private var tableScaleRandom = [Int]()
    
    
    
    
    var body: some View {
        
        VStack {
            Text("❎").font(.largeTitle)
                .imageScale(.large)
                .foregroundColor(.accentColor)
            Spacer()
            Text("Multiplication Challenge  ")
                .font(.largeTitle)
            
            Spacer()
            Text("Choose the multiplication table to test")
            
            Stepper("Multiplication table .. \(multiplier)", value: $multiplier, in: 1...12){_ in
                tableScale.shuffle()
            }
            
            Text("Number of questions").font(.title)
            Picker("Number of questions", selection: $chosenNumberOfQuestions) {
                ForEach(numberOfQuestions, id: \.self) {
                    
                    Text("\($0)")
                       .font(.title)
         
                    

                }
            }.pickerStyle(.segmented)
            
            Text("\(multiplier) X \(tableScale[0]) =").opacity(chosenNumberOfQuestions != 0 ? 1 : 0)
            let result = multiplication(a: multiplier, b: tableScale[0])
            let arrayOfNumbers = generateTwoRandomNumbers(correctAnswer: result)
            ForEach(arrayOfNumbers.shuffled(), id: \.self) { number in
                
               
                Button {
                    numberTapped(number: number, result: result)
                    
                } label: {
                 Text("\(number)").opacity(chosenNumberOfQuestions != 0 ? 1 : 0)
                    
                }
                
                Spacer()
            }
            
            
                
             
        }.alert(scoreTitle, isPresented: $showingScore) {
            Button("Continue", action: askAnotherQuestion)
        } message: {
            Text("Your score is: \(score)")
        }.alert(finalMessage, isPresented: $showingFinalMessage) {
            Button("Start again", action: resetGame)
        } message: {
            Text("Your score is: \(score)")
        }
        .padding()
        
    }
    
    func askAnotherQuestion() {
        tableScale.shuffle()
    }
    
    func multiplication(a: Int, b: Int) -> Int {
        let result = a * b
        return result
    }

    func generateTwoRandomNumbers(correctAnswer: Int) -> [Int] {
        
        let a = Int.random(in: 0...144)
        let b = Int.random(in: 0...144)
        
        let arrayOfRandomNumbers = [correctAnswer, a, b]
        
        return arrayOfRandomNumbers
    }

    func numberTapped(number: Int, result: Int){
        
        if counter < chosenNumberOfQuestions {
            
            if number == result {
                
                scoreTitle = "\(number) is correct! This is your try no. \(counter)"
                counter += 1
                score += 1
                
                print("Hello")
            } else {
                counter += 1
                score -= 1
                
                scoreTitle = "Wrong. The right result is \(result)"
            }
            showingScore = true
        } else if counter == chosenNumberOfQuestions {
            
            if number == result {
                
                scoreTitle = "\(number) is correct! This is your try no. \(counter)"
                counter += 1
                score += 1
                
                print("Hello")
            } else {
                counter += 1
                score -= 1
                
                scoreTitle = "Wrong. The right result is \(result)"
            }
            showingFinalMessage = true
            if score == chosenNumberOfQuestions {
                finalMessage = "Great!"
            } else if score > (score / 2) {
                finalMessage = "Well done!"
            } else {
                finalMessage = "Too bad!!!"
            }
        }
    }
    func resetGame() {
        counter = 1
        score = 0
        multiplier = 1
        chosenNumberOfQuestions = 0
        tableScale.shuffle()
        
    }
   
}



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

在“应用程序”中,用户从提供的三个答案中选择一个,并显示一条警告消息,提示用户回答的正确性,点击“继续”按钮后,将显示一组新的问题和答案。不知何故,问题和答案会发生两次刷新,一次是在提供答案后,另一次是在点击警告窗口上的继续按钮后。

j7dteeu8

j7dteeu81#

你的问题是这3行代码:

let result = multiplication(a: multiplier, b: tableScale[0])
let arrayOfNumbers = generateTwoRandomNumbers(correctAnswer: result)
ForEach(arrayOfNumbers.shuffled(), id: \.self) { number in

你不应该在你的视图代码中计算值。每次你的视图重绘,它都在计算新的值。你想在视图代码之外控制它。
如何修复:

  1. resultarrayOfNumbers应该是@State vars
    1.移动代码以计算resultgenerateTwoNumbersshuffle,将arrayOfNumbers转换为askAnotherQuestion
    1.您需要在Stepper中调用askAnotherQuestion
    1.你需要在启动时触发一个初始的askAnotherQuestion,也许在一个.onAppear()修饰符里面。

相关问题