Author: Yuying Fan
Reviewers: Anthony Li, Jordan Hochman
Please leave feedback by posting on Ed or contacting the course staff.
Required Software: macOS Ventura, Xcode 15
Deadline: Monday, 3/11 @ 11:59 PM
In this assignment, you will create a trivia game application using SwiftUI. This project will consolidate your understanding of UI components, state management, navigation, and app design by applying them to a real-world interactive application. We have laid out some basic requirements and a high-level guide to get you started, but the design and implementation are up to you. Pick your favorite trivia topic and have fun!
Your game application should include:
Text
, Image
, Button
, VStack
, and List
(to display the list of answer choices, for
example).@State
and @Binding
to manage and pass simple data within and between views.ObservableObject
to and use it to manage the game state, such as current question,
selected answer, and score. Use @Published
to update the UI when the state changes.NavigationStack
and NavigationLink
for screen transitions.Implement the Model-View-ViewModel (MVVM) architecture to separate the game logic from the UI.
Question
model that represents a single question.QuizViewModel
that manages the game state.Track and update questions, answers, and scores.
The above are simply some minimum requirements for us to grade your game. We encourage you to add more features and polish your game as much as you like!
Below are some steps to help you get started with your project. You are encouraged to deviate from these steps and add your own features, as long as you still satisfy the requirements listed above.
WelcomeView
, QuestionView
,
and ScoreView
.Question
data model.QuizViewModel
, which will manage
the state of your quiz. This class likely conforms to ObservableObject
.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 three main screens of your trivia game: the Welcome Screen, the Question Screen, and the Score 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.Button
that says "Start Quiz" or similar. Use this button to
navigate to the Question 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 Question Screen. The destination should be your QuestionView
.
The NavigationLink
should be activated by the Start Button, providing a seamless transition
to the quiz.Design the Question 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
and Button
components to align with your app's
design theme.Create the Score Screen:
Text
view to display the player's score. You might also include
a message that vary with the score (e.g., "Great job!" for high scores).Button
components for restarting the game or returning
to the Welcome Screen.VStack
s and modifiers to style and
position your components.Implement Basic Navigation:
NavigationLink
s are properly set up to move between the Welcome, Question, and
Score screens. 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,
and score.QuizViewModel
as a @StateObject
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
class QuizViewModel: ObservableObject {
// MARK: - Properties
@Published var questions: [Question] = [] // Array to store questions
@Published var currentQuestionIndex: Int = 0 // Index of the current question
@Published var selectedAnswer: String? = nil // The user's selected answer
@Published var score: Int = 0 // The user's score
@Published 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:
// 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 Question 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.quizFinished
state in your views to navigate the user to the Score Screen when
all questions have been answered.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.This assignment is out of 100 points, with the following breakdown:
Text
, Image
, Button
, VStack
, and List
components across all screens (2
points each, 10 points total).@State
to manage data locally within a view (5 points).@Binding
to pass data to a child or sibling view (5 points).ObservableObject
for managing the game state, with @Published
properties triggering UI updates (10 points).@ObservedObject
or @StateObject
in views to observe the game state changes (5
points).NavigationStack
and NavigationLink
for smooth screen transitions
(5 points).Question
model representing each question (5 points).QuizViewModel
managing game logic and state, with appropriate
encapsulation of
game logic and separation of concerns (10 points).@StateObject
and/or @ObservedObject
to
initialize and connect to the ViewModel (5 points).Picker
to select the difficulty level of the quiz, or a Slider
to adjust the volume of the sound effects.To submit your homework, zip (or tar.gz) of your entire XCode project folder and upload it to Canvas. Make sure that you've given the requirements another read before you do so.
Submit on Canvas →