이 영역을 누르면 첫 페이지로 이동
Daily Growth 블로그의 첫 페이지로 이동

Daily Growth

페이지 맨 위로 올라가기

Daily Growth

Loving you is the reason I live. That’s why every day is precious, a step toward my dreams and you.

Swift로 만드는 퀴즈 앱: UIKit와 구조체로 구현하는 인터랙티브 UI

  • 2025.06.16 14:54
  • IT

swift 구조체

Swift로 만드는 나만의 퀴즈 앱: UIKit과 구조체

오늘은 UIKit 기반의 간단한 퀴즈 앱 구현 과정을 정리했다✨.  앱은 질문을 표시하고 True/False 버튼을 눌러 정답을 확인하며, 진행 상황을 표시하는 기능까지 포함한다. 개발 과정에서 사용된 주요 Swift 문법 요소는 IBOutlet, IBAction, viewDidLoad, 배열(Array), 조건문, 반복 로직, 그리고 구조체(struct)이다.

 

1. 시작 프로젝트 설정과 UI 연결

Xcode에서 제공하는 기본 ViewController 템플릿을 활용하여 퀴즈 앱 프로젝트를 시작했다. 스토리보드에는 간단한 UI를 구성했다.

  • 질문을 보여줄 UILabel
  • True / False 버튼
  • 진행 상황을 나타내는 UIProgressView

이제 중요한 것은 UI 요소를 코드와 연결하는 것이다.(복습복습~) 이를 위해 IBOutlet과 IBAction을 활용했고, 다음과 같이 연결했다.

@IBOutlet weak var questionLabel: UILabel!
@IBOutlet weak var progressBar: UIProgressView!
@IBOutlet weak var trueButton: UIButton!
@IBOutlet weak var falseButton: UIButton!

버튼을 누를 때 동작하도록 IBAction도 추가하기:)

@IBAction func answerButtonPressed(_ sender: UIButton) {
    // 이후 로직에서 활용됨
}

 

 

2. 앱 초기화와 첫 질문 출력

iOS 앱에서 화면이 처음 로드될 때 실행되는 함수가 viewDidLoad()이다. 여기서 첫 질문을 화면에 띄우기 위해 코드를 작성했다.

override func viewDidLoad() {
    super.viewDidLoad()
    questionLabel.text = "4 + 2는 6이다"
}

하지만 질문이 하나만 있는 퀴즈 앱은 너무 심심하다. 그래서 질문을 배열로 관리해- 여러 질문을 표시할 수 있도록 하자(:

let quiz = ["4 + 2는 6이다", "5 + 3은 1보다 크다", "3 + 8은 10보다 작다"]

 

 

3. 배열과 동적 UI 업데이트

단순한 배열로 질문을 다루다 보니, 다음 질문으로 넘어가는 로직이 필요했다. 이를 위해 questionNumber라는 변수를 선언하고, 버튼이 눌릴 때마다 증가시키도록 했다.

var questionNumber = 0

@IBAction func answerButtonPressed(_ sender: UIButton) {
    questionNumber += 1
    updateUI()
}

UI 업데이트는 별도의 함수로 분리해 재사용성과 가독성을 높였다.

func updateUI() {
    questionLabel.text = quiz[questionNumber]
}

하지만 문제 발생! 질문을 모두 표시하고 난 뒤 버튼을 누르면 앱이 강제 종료됐다. 이는 배열의 인덱스 범위를 벗어나기 때문이었다. 이 오류를 해결하기 위해 안전하게 배열 범위를 검사하거나, 퀴즈가 끝났을 때 처음으로 되돌아가도록 로직을 수정해야 한다.

if questionNumber < quiz.count - 1 {
    questionNumber += 1
} else {
    questionNumber = 0
}

 

 

4. 정답 비교와 2차원 배열

퀴즈 앱의 목적은 단순히 질문을 보여주는 것이 아니라, 사용자의 정답을 비교하고 피드백을 주는 것이다. 이를 위해 각 질문과 정답을 쌍으로 묶어 관리하는 2차원 배열을 도입했다.

let quiz = [
    ["4 + 2는 6이다", "True"],
    ["5 + 3은 1보다 크다", "True"],
    ["3 + 8은 10보다 작다", "False"]
]

그리고 버튼을 누르면, 사용자 입력과 정답을 비교해 출력하는 로직을 추가하기~

let userAnswer = sender.currentTitle! // "True" or "False"
let actualAnswer = quiz[questionNumber][1]

if userAnswer == actualAnswer {
    print("정답입니다!")
} else {
    print("틀렸습니다.")
}

 

5. 구조체(struct)를 활용한 데이터 리팩토링

2D 배열로 퀴즈를 다루다 보니 인덱스를 두 번 써야 해서 코드가 읽기 어려워졌다. 이를 개선하기 위해 Swift의 구조체를 도입했다. 구조체를 사용하면 데이터의 의미를 명확하게 하고, 더 유지보수하기 좋은 코드를 만들 수 있기 때문이다:)

struct Question {
    let title: String
    let answer: String
}

이제 퀴즈 배열은 이렇게 바뀐다.

let quiz = [
    Question(title: "4 + 2는 6이다", answer: "True"),
    Question(title: "5 + 3은 1보다 크다", answer: "True"),
    Question(title: "3 + 8은 10보다 작다", answer: "False")
]

그리고 질문과 정답 접근도 훨씬 간결해졌다.

questionLabel.text = quiz[questionNumber].title

let actualAnswer = quiz[questionNumber].answer

 

*데이터 리팩토링(Data Refactoring이란?

📌 개념 데이터 구조를 더 잘 정돈하는 리팩토링 방식
🎯 목적 가독성, 유지보수성, 타입 안정성 향상
🛠 방법 구조체 사용, 의미 있는 이름 부여, 타입 명확화
✅ 효과 실수 방지, 기능 추가 쉬움, 협업 용이

 

6. 구조체 딥 다이브: 청사진과 개체

퀴즈 앱을 만들다 보니 구조체가 얼마나 강력한지 깨달았다. 구조체는 단순히 데이터를 담는 그릇을 넘어서, 관련된 동작(메서드)까지 정의할 수 있는 하나의 독립된 개체다.

예를 들어 아래와 같은 Town 구조체를 만들 수 있다:)

struct Town {
    let name: String
    var citizens: [String]
    var resources: [String: Int]

    func fortify() {
        print("Defences increased!")
    }
}

그리고 이 구조체를 기반으로 마을을 만들 수 있다는 것~

var myTown = Town(name: "AngelaLand", citizens: ["Angela", "Jack"], resources: ["Grain": 100])

Town은 이름, 시민, 자원을 갖고 있으며, fortify() 같은 메서드도 가질 수 있다. 이는 곧 앞으로 업데이트할 퀴즈 앱의 Question 구조체도 더 풍부한 기능을 담을 수 있다는 의미!🧚🏻

 


이 퀴즈 앱 구현 과정은 Swift 문법과 UIKit의 기초적인 사용법을 통합적으로 연습할 수 있는 예제이다. 특히 다음과 같은 개념을 실전에서 사용할 수 있다:

  • IBOutlet/IBAction을 통한 UI와 코드 연결
  • viewDidLoad()의 역할
  • 배열 및 조건문을 활용한 흐름 제어
  • 구조체를 이용한 데이터 구조 설계

이후에는 구조체에 로직을 포함하거나, MVC 패턴을 적용해 구조적인 앱 아키텍처로 발전시킬 수 있다. iOS 개발 초반에 적합한 실습 예제이며, 기본 개념을 확실히 다지는 데 유용하다:)

반응형

'IT' 카테고리의 다른 글

Swift 앱 개발에서 struct로 배우는 코드 구조의 힘  (1) 2025.06.18
Swift 구조체(struct) 실습: 사용자 정보 설계와 메서드 작성  (0) 2025.06.17
iOS 타이머 앱 구현 예제: Swift로 시간 카운트다운 + mp3 재생까지  (0) 2025.06.15
Swift Optional과 Dictionary로 데이터 다루는 실용적인 방법  (3) 2025.06.13
Swift 코드 가독성을 바꾸는 switch 문 핵심정리  (1) 2025.06.12

댓글

이 글 공유하기

  • 구독하기

    구독하기

  • 카카오톡

    카카오톡

  • 라인

    라인

  • 트위터

    트위터

  • Facebook

    Facebook

  • 카카오스토리

    카카오스토리

  • 밴드

    밴드

  • 네이버 블로그

    네이버 블로그

  • Pocket

    Pocket

  • Evernote

    Evernote

다른 글

  • Swift 앱 개발에서 struct로 배우는 코드 구조의 힘

    Swift 앱 개발에서 struct로 배우는 코드 구조의 힘

    2025.06.18
  • Swift 구조체(struct) 실습: 사용자 정보 설계와 메서드 작성

    Swift 구조체(struct) 실습: 사용자 정보 설계와 메서드 작성

    2025.06.17
  • iOS 타이머 앱 구현 예제: Swift로 시간 카운트다운 + mp3 재생까지

    iOS 타이머 앱 구현 예제: Swift로 시간 카운트다운 + mp3 재생까지

    2025.06.15
  • Swift Optional과 Dictionary로 데이터 다루는 실용적인 방법

    Swift Optional과 Dictionary로 데이터 다루는 실용적인 방법

    2025.06.13
다른 글 더 둘러보기

정보

Daily Growth 블로그의 첫 페이지로 이동

Daily Growth

  • Daily Growth의 첫 페이지로 이동

검색

메뉴

    카테고리

    • 분류 전체보기 (470)
      • Design History (69)
      • IT (170)
      • Typography (13)
      • UX • UI Design (11)
      • Money (62)
      • Health (53)
      • Words (6)
      • Reading (21)
      • English (64)

    나의 외부 링크

    • Daily Growth
    • Daily World
    • lody.design
    • lody.diary

    정보

    self-improvement의 Daily Growth

    Daily Growth

    self-improvement

    블로그 구독하기

    • 구독하기
    • 네이버 이웃 맺기
    • RSS 피드

    방문자

    • 전체 방문자
    • 오늘
    • 어제

    티스토리

    • 티스토리 홈
    • 이 블로그 관리하기
    • 글쓰기
    Powered by Tistory / Kakao. Copyright © self-improvement.

    티스토리툴바