Project 2 — Guess the Flag
Соберём короткую викторину: приложение показывает три флага, просит найти страну и ведёт счёт. Главная новая тема — layout из stacks и интерактивность кнопок.
Готовность к проекту
0 из 6 рекомендуемых тем изучено. Проект всегда доступен — это не ограничение.
Рабочий vertical slice
Код использует emoji вместо внешних картинок, поэтому компилируется в новом SwiftUI-проекте без дополнительных assets.
import SwiftUI
struct Country: Identifiable {
let id = UUID()
let name: String
let flag: String
}
struct ContentView: View {
@State private var countries = [
Country(name: "Франция", flag: "🇫🇷"),
Country(name: "Германия", flag: "🇩🇪"),
Country(name: "Италия", flag: "🇮🇹"),
Country(name: "Испания", flag: "🇪🇸"),
Country(name: "Украина", flag: "🇺🇦")
].shuffled()
@State private var correctAnswer = Int.random(in: 0...2)
@State private var score = 0
@State private var result = ""
@State private var showingResult = false
var body: some View {
ZStack {
LinearGradient(colors: [.indigo, .black], startPoint: .top, endPoint: .bottom)
.ignoresSafeArea()
VStack(spacing: 24) {
Text("Найдите флаг страны")
.foregroundStyle(.white.secondary)
Text(countries[correctAnswer].name)
.font(.largeTitle.bold())
.foregroundStyle(.white)
ForEach(0..<3) { index in
Button {
answer(index)
} label: {
Text(countries[index].flag)
.font(.system(size: 72))
.frame(maxWidth: .infinity)
}
.accessibilityLabel("Флаг: \(countries[index].name)")
}
Text("Счёт: \(score)")
.foregroundStyle(.white)
}
.padding()
}
.alert(result, isPresented: $showingResult) {
Button("Дальше", action: nextQuestion)
}
}
private func answer(_ index: Int) {
let isCorrect = index == correctAnswer
score += isCorrect ? 1 : 0
result = isCorrect ? "Верно" : "Это \(countries[index].name)"
showingResult = true
}
private func nextQuestion() {
countries.shuffle()
correctAnswer = Int.random(in: 0...2)
}
}
#Preview { ContentView() }Сначала проверьте полный цикл «вопрос → ответ → alert → следующий вопрос». Счётчик раундов добавляется самостоятельным изменением в конце статьи.
Данные и состояние игры
@State private var countries = ["Estonia", "France", "Germany", "Ireland", "Italy", "Nigeria", "Poland", "Spain", "UK", "Ukraine", "US"].shuffled()
@State private var correctAnswer = Int.random(in: 0...2)
@State private var score = 0Array, Range и случайное число — обычный Swift. @State сообщает SwiftUI, что после изменения вопроса или счёта экран нужно обновить.
VStack, HStack и ZStack
VStack располагает View вертикально, HStack — горизонтально, ZStack накладывает слои друг на друга. Фон удобно поместить первым элементом ZStack, а текст и кнопки — поверх него.
ZStack {
LinearGradient(colors: [.blue, .black], startPoint: .top, endPoint: .bottom)
.ignoresSafeArea()
VStack {
Text("Guess the Flag")
// Вопрос и кнопки
}
}🧠 Разберём через знакомое
Уже знакомо
- Swift✓ Structs
- Swift✓ Protocols
Новое
- SwiftUI→ VStack
- SwiftUI→ HStack
- SwiftUI→ ZStack
- SwiftUI→ View modifiers
Button получает closure
ForEach(0..<3) { number in
Button {
flagTapped(number)
} label: {
Image(countries[number])
.clipShape(.capsule)
.shadow(radius: 5)
}
}Тело Button — closure: оно выполняется после нажатия. label тоже описан closure, но возвращает интерфейс кнопки. ForEach соединяет Swift Range и SwiftUI View.
Проверка ответа и Alert
func flagTapped(_ number: Int) {
if number == correctAnswer {
score += 1
} else {
score -= 1
}
showingScore = true
}Функция и if уже знакомы. Новое — alert, который зависит от @State и вызывает следующий вопрос после закрытия.
.alert(scoreTitle, isPresented: $showingScore) {
Button("Continue", action: askQuestion)
} message: {
Text("Your score is \(score)")
}Испытание
Задание
Проведи восемь раундов, затем покажи итоговый результат и кнопку новой игры. При ошибке укажи название выбранной страны.Что уже нужно знать
Состояние, условия, functions, `alert` и обновление Array.Показать подсказку 1
Показать подсказку 2
Показать решение
func askQuestion() {
questionCount += 1
if questionCount == 8 {
showingFinalScore = true
} else {
countries.shuffle()
correctAnswer = Int.random(in: 0...2)
}
}Что ты сейчас использовал
Swift Знакомые основы
SwiftUI Новое в проекте
- + View
- + @State
- + VStack
- + HStack
- + ZStack
- + Button
- + Image
- + Alert
- + View modifiers
Дальше разберём, почему modifiers возвращают новые View и как выносить повторяющееся оформление. Project 3 →
Комментарии
Вопросы, находки и подсказки по этой странице.
Войди, чтобы задать вопрос или помочь другим.