카테고리 없음

SwiftUI에서 ForEach와 Identifiable 프로토콜 활용하기

ragdoll-cat 2025. 2. 20. 09:14

SwiftUI에서 ForEach와 Identifiable 프로토콜 활용하기

 

✅ SwiftUI에서 리스트를 다룰 때 필수적인 ForEach와 Identifiable

 

SwiftUI에서는 ForEachIdentifiable 프로토콜을 활용하여 반복적인 UI 요소를 효율적으로 만들 수 있습니다. 특히, ListVStack, HStack 등에서 여러 개의 데이터를 표시할 때 유용합니다.

 

이 글에서는 ForEachIdentifiable 프로토콜의 개념과 활용 방법을 자세히 설명하겠습니다.


1️⃣ ForEach란 무엇인가?

 

ForEach는 SwiftUI에서 반복적으로 뷰를 생성하는 데 사용되는 구조체입니다. Swift의 for-in 루프처럼 동작하지만, SwiftUI의 선언형 문법에 맞게 설계되었습니다.

 

📌 기본 문법

ForEach(컬렉션, id: \.키) { 요소 in  
    // 반복할 뷰
}

컬렉션: 배열(Array) 또는 범위(Range)를 사용할 수 있습니다.

id: \.키: 각 요소를 식별하는 고유한 값(ID)입니다.

{ 요소 in ... }: 각 요소에 대해 실행할 뷰를 정의합니다.


2️⃣ ForEach를 활용한 기본 예제

 

배열을 사용하여 간단한 리스트를 만들 수 있습니다.

import SwiftUI

struct ContentView: View {
    let fruits = ["🍎 사과", "🍌 바나나", "🍇 포도", "🍉 수박"]

    var body: some View {
        VStack {
            Text("과일 리스트")
                .font(.title)
                .padding()
            
            ForEach(fruits, id: \.self) { fruit in
                Text(fruit)
                    .font(.headline)
                    .padding()
            }
        }
    }
}

📝 코드 설명

1. fruits 배열에 과일 이름을 저장합니다.

2. ForEach(fruits, id: \.self)를 사용하여 각 과일을 리스트에 출력합니다.

3. id: \.self를 사용하여 문자열을 직접 고유 식별자로 활용합니다.

 

📌 주의: 배열의 요소가 String, Int 같은 값 타입일 경우, id: \.self를 사용하여 고유성을 보장할 수 있습니다. 하지만, 사용자 정의 모델 객체일 경우 Identifiable 프로토콜을 구현하는 것이 더 좋습니다.


3️⃣ Identifiable 프로토콜을 활용한 데이터 리스트

 

배열에 String 같은 기본 타입이 아닌, 사용자 정의 데이터 모델을 사용할 경우에는 각 항목을 고유하게 식별할 방법이 필요합니다.

이때 Identifiable 프로토콜을 채택하면 id를 자동으로 인식하여 ForEach에서 id: \.self를 명시할 필요가 없습니다.

 

📌 Identifiable 프로토콜 구현 예제

import SwiftUI

// Identifiable 프로토콜을 준수하는 데이터 모델
struct Fruit: Identifiable {
    let id = UUID() // 고유한 ID
    let name: String
}

struct ContentView: View {
    let fruits = [
        Fruit(name: "🍎 사과"),
        Fruit(name: "🍌 바나나"),
        Fruit(name: "🍇 포도"),
        Fruit(name: "🍉 수박")
    ]

    var body: some View {
        VStack {
            Text("과일 리스트")
                .font(.title)
                .padding()
            
            List(fruits) { fruit in
                Text(fruit.name)
                    .font(.headline)
            }
        }
    }
}

📝 코드 설명

1. Fruit 구조체가 Identifiable 프로토콜을 채택합니다.

id 속성을 UUID()로 설정하여 각 객체가 고유한 ID를 가집니다.

2. fruits 배열은 Fruit 객체의 리스트입니다.

3. List(fruits) { fruit in ... } 형태로 ForEach 없이도 리스트가 자동으로 생성됩니다.

Identifiable을 준수하기 때문에 id: \.self를 명시할 필요가 없습니다.

 

📌 Tip: Identifiable을 사용하면 UUID()뿐만 아니라, 데이터베이스의 고유 ID(예: 사용자 ID, 제품 코드)도 사용할 수 있습니다.


4️⃣ ForEach와 Identifiable을 활용한 동적 UI 예제

 

아래 예제에서는 사용자가 직접 데이터를 추가할 수 있는 리스트를 만들어 보겠습니다.

import SwiftUI

struct Task: Identifiable {
    let id = UUID()
    let title: String
}

struct ContentView: View {
    @State private var tasks: [Task] = []
    @State private var newTask: String = ""

    var body: some View {
        VStack {
            Text("할 일 목록")
                .font(.title)
                .padding()

            HStack {
                TextField("할 일을 입력하세요", text: $newTask)
                    .textFieldStyle(RoundedBorderTextFieldStyle())
                    .padding()
                
                Button(action: {
                    if !newTask.isEmpty {
                        tasks.append(Task(title: newTask))
                        newTask = "" // 입력 필드 초기화
                    }
                }) {
                    Text("추가")
                        .padding()
                        .background(Color.blue)
                        .foregroundColor(.white)
                        .cornerRadius(8)
                }
            }

            List(tasks) { task in
                Text(task.title)
            }
        }
        .padding()
    }
}

📝 코드 설명

1. Task 구조체가 Identifiable을 준수하여 id를 자동 인식합니다.

2. @State를 사용하여 tasks 배열을 동적으로 관리합니다.

3. TextField에서 입력받은 값을 tasks 배열에 추가하는 기능을 구현합니다.

4. List(tasks) { task in ... } 형태로 리스트를 동적으로 렌더링합니다.


5️⃣ ForEach에서 인덱스 활용하기

 

ForEachenumerated() 메서드와 함께 사용하면 인덱스를 활용할 수도 있습니다.

let items = ["🍕 피자", "🍔 버거", "🍣 초밥"]

ForEach(Array(items.enumerated()), id: \.element) { index, item in
    Text("\(index + 1). \(item)")
}

📌 Tip: id: \.element를 사용하여 각 항목을 고유하게 식별합니다.


✨ 마무리

 

SwiftUI에서 ForEachIdentifiable은 리스트 형태의 UI를 만들 때 필수적인 개념입니다.

 

핵심 정리

ForEach는 컬렉션의 각 요소를 반복하여 뷰를 생성합니다.

값 타입(String, Int)을 사용할 경우 id: \.self를 지정해야 합니다.

사용자 정의 데이터 모델을 사용할 경우 Identifiable 프로토콜을 채택하여 id를 설정하는 것이 좋습니다.

ForEach를 활용하여 동적 UI를 구성하고, 리스트를 효율적으로 관리할 수 있습니다.