Making a screen update from a separate file

Hi,

I am a Computer Science teacher who has just taken over a department. One of the students is using Swift to develop a multiple choice quiz app and I have no idea how to use Swift so am seeking some help.

I have created the following two files but when the question number updates in the brainQuiz instance of the QuizBrain file it is not updating the ControlView i.e. showing the next question in the data structure.

This is ContentView
import SwiftUI
var brainQuiz = QuizBrain()
struct ContentView: View {

var body: some View {
    
    VStack {
        //Getting the question text from the data structure in QuizBrain
        Text(brainQuiz.questions[brainQuiz.numQuestion].text)
        
        //Getting the question text from the data structure in QuizBrain
        Image(brainQuiz.questions[brainQuiz.numQuestion].imageName)
        
        Spacer()
        
        VStack {
            
            ForEach (brainQuiz.questions[brainQuiz.numQuestion].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)
                }
            }
           
        }//vstack
        .padding()
        
    }//vstack
    
}//View

}//struct

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

This is QuizBrain
import Foundation
import SwiftUI

struct QuizBrain{

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")
]

var numQuestion = 0
var score = 0
    
mutating func checkAns(userAnswer: String){
    if userAnswer == questions[numQuestion].ans[0]{
        score += 1
        print("Correct")
    }
    
    //If there are still questions...
    if numQuestion + 1 <= questions.count{
        numQuestion += 1 //changing the number here is not affecting the output on the screen
        print(numQuestion)
      
    }else{
        //quizcompleted = true
        numQuestion = 0
        
    }
    
}

}

Any help would be great!

Thanks
Emma

Please note that this forum is primarily for questions laser focused on the swift programming language itself and its standard library. SwiftUI related questions are better discussed on other forums like stackoverflow or apple dev forums.


Option A: just move brainQuiz to be a view state:

struct ContentView: View {
    @State var brainQuiz = QuizBrain()
    ...

Option B: make QuizBrain an observable object:

class QuizBrain: ObservableObject { // Note class and "ObservableObject" here
    let questions = [ // doesn't change so no need to make it published
        ...
    ]
    @Published var numQuestion = 0 // publishing changes to this variable
    @Published var score = 0 // publishing changes to this variable
    // hense @Published
        
    func checkAns(userAnswer: String) { // this is now class, so "mutating" is not needed
        ...
    }
}

struct ContentView: View {
    @StateObject private var brainQuiz = QuizBrain() // observing changes in this model
    ....
}

Worth watching some introductory videos on SwiftUI essentials, like this one.

1 Like

Thank you so much for your help! Disclaimer