Below are some steps to help you get started with HW2: Trivia Game. You are encouraged to deviate from these steps and add your own features, as long as you still satisfy the requirements listed in the assignment.
WelcomeView
and GameView
.Question
data model.QuizViewModel
, which will manage the state of your quiz. This class is likely labelled with @Observable
.Define a Question
struct that represents a single question in your trivia game. It should have properties for the question text, question image, answer options, and the correct answer.
Here's an example of what your Question
struct might look like:
struct Question {
var text: String // The question text
var imageName: String // Name of the local image file associated with the question
var answers: [String] // The possible answers
var correctAnswer: String // The correct answer
}
We now proceed to create the UI for the two main screens of your trivia game: the Welcome Screen and then Game Screen. Use dummy data for now to test your UI components.
Develop the Welcome Screen:
VStack
to vertically stack your Text
and Button
elements. This will be your welcome message and the button to start the game.Text
views for your game's title and brief instructions. Apply font modifiers to adjust the size and weight to make them stand out.Text
field to display the highscore value.Button
that says "Start Quiz" or similar. Use this button to navigate to the Game Screen. Style the button with padding, background, and font modifiers to make it visually appealing.Set Up Navigation:
NavigationStack
. This enables navigation between screens in your app.VStack
on the Welcome Screen, add a NavigationLink
that leads to the Game Screen. The destination should be your GameView
. The NavigationLink
should be the Start Button, providing a seamless transition to the quiz. Alternatively, you can push to a NavigationPath
from a Button
.Design the Game Screen:
VStack
, HStack
, or ZStack
to lay out your question and answer options. The question should be at the top, followed by the answer options listed below. Use a List
to display the answer options.Text
views for displaying the question and each answer option. Ensure the text is legible and well-spaced for easy readability.Button
. These buttons should have action handlers that determine what happens when an answer is selected (e.g., display the correct answer, update the score, move to the next question).Text
view to display the player's score somewhere on the screen.Button
components for restarting the game or returning to the Welcome Screen.Text
and Button
components to align with your app's design theme.Finish Basic Navigation:
NavigationLink
s are properly set up to move between the Welcome and Game Screens (going both ways). Test the flow to make sure buttons take you to the correct screens.Set Up Your ViewModel:
QuizViewModel
class. This class will manage the game state and logic, including the current question, selected answer, score, and highscore.QuizViewModel
as @State
in your main game view (typically the first screen of your game, such as the Welcome Screen). This ensures the state is retained throughout the lifecycle of the view.QuizViewModel
might look like:import Foundation
import SwiftUI
@Observable
class QuizViewModel {
// MARK: - Properties
var questions: [Question] = [] // Array to store questions
var currentQuestionIndex: Int = 0 // Index of the current question
var selectedAnswer: String? = nil // The user's selected answer
var score: Int = 0 // The user's score
var highscore: Int = 0 // The user's highscore
var quizFinished: Bool = false // Flag to determine if the quiz has finished
// MARK: - Initialization
init() {
loadQuestions() // Call to load questions into the array
}
// MARK: - Methods
/// Initializes questions array with data.
func loadQuestions() {
// Hard-coded questions with local images
self.questions = [
// Add questions here. Example:
// Question(text: "What is not a valid source of images in SwiftUI?",
// imageName: "swift-image",
// answers: ["System Icon", "Image Name", "URL", "Doodle on My Desk"],
// correctAnswer: "Doodle on my desk")
]
}
/// Processes the selected answer, updates the score and advances to the next question.
func submitAnswer() {
// Functionality to be implemented: check the selected answer, update score, move to next question or finish quiz.
}
/// Resets the quiz to its initial state for a new game.
func resetQuiz() {
// Functionality to be implemented: reset current question index, score, and quiz finished status; reload questions.
}
}
Implement the Quiz Logic:
QuizViewModel
, write a method to load questions into your questions array. This can be from a static array for now, but you may revisit the app later in the course to replace it with a method that fetches questions from an API or database.currentQuestionIndex
to keep track of which question the user is on. This will help you fetch the current question from the questions array and display it on the Game Screen.Bind ViewModel to Views:
selectedAnswer
and call the method to submit the answer.Handle Game Completion:
currentQuestionIndex
is equal to the length of your questions array minus one.quizFinished
boolean flag in your ViewModel to true (and the highscore!).quizFinished
state in your views to navigate the user to the Welcome Screen when all questions have been answered (or to a separate Score Screen if you wish).Resetting the Game:
QuizViewModel
, implement a resetQuiz
method that resets the currentQuestionIndex
, score
, and quizFinished
status, and reloads the questions. This allows the user to start a new game once they have finished.resetQuiz
method to allow users to play again from the beginning without having to restart the app.