
Command Line에서 완성한 심플한 퀴즈앱 참조
https://dailyblessing.tistory.com/236
[iOS/Xcode] 기초 연습문제를 통한 프로그래밍 이해하기 4편
6. 함수 shuffled() 를 활용하여 랜덤 퀴즈 출제출처: https://dailyblessing.tistory.com/228 [싸디아재의 시선과 흐름:티스토리] 이전 글 어제는 shuffled() 함수를 사용하여 퀴즈를 랜덤하게 출제하는
dailyblessing.tistory.com
앞서 프로그래밍 공부 4편에서 간단한 퀴즈게임을 만들어봤다.
그후에 구조와 함수 등 기초 단계를 공부해 보았으니 다음 단계는 Command Line에 있는 코드를 SwiftUI로 가져와서 시각적인 요소들을 추가하여 앱 같은 모습이 되도록 코딩을 해보려 한다.
프로젝트에 swiftUI interface 기반으로 생성하는 부분은 생략하겠다.
오늘의 목표는 Command Line에서 만든 퀴즈 앱을 SwiftUI 앱으로 리메이크! 단계적으로 옮기면서 SwiftUI 개념까지 자연스럽게 익히는 방식이 될 것이다. SwiftUI에 적응을 해야할 단계.
전체 구조를 다음과 같이 옮기는 것으로 구상을 했다.
| 단계 | 내용 |
| 1단계 | 문제 보여주기 + O/X 버튼으로 정답 선택 |
| 2단계 | 정답/오답 처리 + 점수 계산 |
| 3단계 | 퀴즈 끝나면 결과 화면 보여주기 |
| 4단계 | 오답 복습 또는 다시 풀기 기능 |
| 5단계 | 카테고리 선택 UI 추가 (옵션) |
ContentView.swift에 코딩을 진행할 것이다. 구조적으로 변하는 것들이 있는데 최대한 정리해 보도록 하겠다.
1. 1단계 : 문제 보여주기 + O/X 버튼으로 정답 선택
먼저 앞전에 Command Line에서 작성된 quizList를 살펴보겠다. quizCategory포함하여.
let quizCategory = [
"General": [
("지구는 태양을 돈다.", "o"),
("지구는 태양을 돈다.", "o"),
("물은 불보다 가볍다.", "o"),
("사람은 4개의 심장을 가지고 있다.", "x"),
("2024년도 12월 3일 발동한 비상계엄은 불법이다.", "O"),
("이스탄불은 대한민국 도시 중 하나이다.", "X"),
("챗GPT는 바보다.", "X")
],
"IT": [
("Swift는 애플에서 만든 언어이다.", "o"),
("HTML은 프로그래밍 언어다.", "x"),
("Xcode는 안드로이드 앱을 개발하는 툴이다.", "x"),
("iPhone은 안드로이드 기반이다.", "x"),
("Windows OS를 개발한 회사는 Microsoft이다.", "o")
],
"History": [
("광복절은 8월 15일이다.", "o"),
("조선은 고구려보다 먼저 생겼다.", "x"),
("세종대왕은 훈민정음을 만들었다.", "o"),
("대략 조선이 건국된 1392년부터 대한제국이 멸망된 1910년까지를 조선시대로 잡고 있다.", "o"),
("고구려는 서기전 1세기부터 668년까지 존속한 고대 왕국으로, 압록강 중류 지역에서 시작되다", "o")
] ]
위 코드는 Command Line에서 작성된 코드이다. 이를 SwiftUI로 옮기면 아래와 같다.
struct Question {
let text: String
let answer: String // "O" or "X"
}
let quizList = [
Question(text: "지구는 태양을 돈다.", answer: "O"),
Question(text: "HTML은 프로그래밍 언어다.", answer: "X")
]
우선 로직 단순화를하고 순차적으로 값을 추가하도록 하겠다. Category도 이후에 추가하겠다.
이제 ContentView.swift를 만들 아래 코드를 넣어주자.
import SwiftUI
struct ContentView: View {
@State private var currentIndex = 0
@State private var score = 0
@State private var showResult = false
struct Question {
let text: String
let answer: String // "O" or "X"
}
let quizList: [Question] = [
Question(text: "지구는 태양을 돈다.", answer: "O"),
Question(text: "HTML은 프로그래밍 언어다.", answer: "X")
]
var body: some View {
VStack(spacing: 30) {
if !showResult {
Text(quizList[currentIndex].text)
.font(.title)
.padding()
HStack(spacing: 40) {
Button("O") {
checkAnswer("O")
}
.buttonStyle(.borderedProminent)
Button("X") {
checkAnswer("X")
}
.buttonStyle(.borderedProminent)
}
} else {
Text("퀴즈 종료!")
Text("당신의 점수는 \(score)점입니다")
// 여기에 다시 시작 버튼 넣어도 되고, 결과 뷰로 이동시켜도 됨
}
}
}
func checkAnswer(_ userAnswer: String) {
if userAnswer.uppercased() == quizList[currentIndex].answer.uppercased() {
score += 1
}
if currentIndex + 1 < quizList.count {
currentIndex += 1
} else {
showResult = true
}
}
}
#Preview {
ContentView()
}
여기서 처음보는 것부터 궁금한 것들이 보였다. 내가 궁금했던건 아래와 같다.
VStack vs HStack은 뭘까?
| 이름 | 정렬 방향 | 예시 |
| VStack | 세로 방향으로 정렬 | 위에서 아래로 쭉 |
| HStack | 가로 방향으로 정렬 | 왼쪽에서 오른쪽으로 쭉 |
아래 예시를 보면 쉽게 이해할 수 있을 것이다.
VStack {
Text("A")
Text("B")
Text("C")
}
// A
// B
// C
HStack {
Text("A")
Text("B")
Text("C")
}
// A B C


VStack(spacing: )과 HStack(spacing: )는 뭘까?
VStack(spacing: 20) {
Text("첫 줄")
Text("둘째 줄")
}
HStack(spacing: 40) {
Text("왼쪽")
Text("오른쪽")
}
VStack(spacing: 20)은 "첫 줄"과 "둘째 줄" 사이의 세로 간격을 말하는 것이고
HStack(spacing: 40)은 "왼쪽"과 "오른쪽" 사이의 가로 간력을 말하는 것이다. spacing: (숫자)를 넣어 요소 사이의 간격을 조정할 수 있다.
.buttonStyle(.borderedProminent)는 뭘까?
이건 SwiftUI에서 버튼의 스타일을 지정하는 방법이라고 한다. 스타일 몇개를 아래와 같이 알아보자.
| 스타일 명 | 효과 |
| .borderedProminent | 배경이 채워진 강조 버튼 (파란색처럼 보임) |
| .bordered | 테두리만 있는 버튼 |
| .plain | 기본 텍스트처럼 생긴 버튼 |
이걸 쓰면 버튼이 강조된 형태(색상, 크기)로 보이게 돼서 “눌러야 할 버튼” 느낌을 줄 수 있을 것 같다.
스타일은 당연히 이보다 많을 것이지만 아직은 배우지 않았기에 나중에 하나씩 배우는데로 포스팅하도록 하겠다.
func checkAnswer(_ userAnswer: String) 설명
처음에는 알듯 말듯 했다. 하지만 결국 찾아보게 되었다.
func checkAnswer(_ userAnswer: String)
설명을 하자면 아래와 같다.
- checkAnswer: 함수 이름
- userAnswer: String: 매개변수 이름은 userAnswer, 타입은 String
- 앞의 _는 외부에서 이 함수를 호출할 때 매개변수 이름을 생략할 수 있게 해줌
앞의 _는 외부에서 이 함수를 호출할 때 매개변수 이름을 생략할 수 있게 해줌? 이게 무슨 뜻이지?
앞으로 Swift 문법 중에서도 함수 문법을 정말 이해해야 하는게 핵심 포인트라는 이야기를 어디서 읽은 기억이 있어서 바로 찾아봐야겠다. 내가 이해한데로 정리를 해보도록 하겠다.
함수에서 func 함수이름(_ 매개변수이름: 타입)처럼 앞에 _가 있으면 → 함수를 호출할 때 매개변수 이름을 안 써도 된다고 한다.
바로 예제로 들어가보자.
func greet(name: String) {
print("안녕하세요, \(name)님!")
}
매개변수 이름을 생략하지 않는 경우에는 함수 greet를 호출할 때는 아래와 같이 매개변수이름을 꼭 써야한다고 한다.
greet(name: "지민") // ✅ 'name:'을 꼭 써야 함!
하지만 매개변수 이름을 생략한 경우(_ 사용)
func greet(_ name: String) {
print("안녕하세요, \(name)님!")
}
함수 호출을 할 때는 매개변수없이 바로 호출이 가능하다고 한다.
greet("지민") // ✅ 매개변수 이름 없이 바로 호출 가능!
Swift에는 기본적으로 이런 규칙이 있다고 한다.
- 첫 번째 매개변수는 기본적으로 외부 이름 생략
- 두 번째 매개변수부터는 외부 이름 붙이는 걸 권장
그리고 외부 이름과 내부 이름 개념이 있다고 한다.
| 위치 | 의미 | 예시 |
| 외부 이름 | 함수 호출할 때 사용하는 이름 | name: |
| 내부 이름 | 함수 내부에서 쓰는 이름 | name |
아래와 같은 식으로 따로 지정도 가능하지만 거의 쓰지 않는다고 한다.
func greet(externalName internalName: String)
다시 Swift의 기본 규칙으로 돌아가서 직접 func checkAnswer(_ answer: String)처럼 _를 쓰면, 명시적으로 "이거 외부 이름 생략할게요"라고 알려주는 거라고 한다.
'개인공부' 카테고리의 다른 글
| [iOS/Xcode] 기초 연습문제를 통한 프로그래밍 이해하기 8편: SwiftUI 공부 시작 iPhone iOS (0) | 2025.03.26 |
|---|---|
| [iOS/Xcode] 기초 연습문제를 통한 프로그래밍 이해하기 7편: SwiftUI 공부 시작 iPhone iOS (0) | 2025.03.26 |
| [iOS/Xcode] 기초 연습문제를 통한 프로그래밍 이해하기 6편 (1) | 2025.03.25 |
| [iOS/Xcode] 기초 연습문제를 통한 프로그래밍 이해하기 5편 (1) | 2025.03.25 |
| [iOS/Xcode] 기초 연습문제를 통한 프로그래밍 이해하기 4편 (2) | 2025.03.25 |