Notice
Recent Posts
Recent Comments
Link
«   2025/04   »
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30
Archives
Today
Total
관리 메뉴

J

[SwiftUI] ForEach in SwiftUI 본문

SwiftUI

[SwiftUI] ForEach in SwiftUI

yujaehui 2024. 5. 13. 12:02

ForEach in SwiftUI

ForEach는 SwiftUI에서 컬렉션의 요소를 반복(iterate)하여 동적으로 뷰를 생성할 때 사용하는 뷰.

SwiftUI는 선언적 UI 프레임워크이므로 반복문(for-in) 대신 ForEach를 사용하여 간결하고 효율적인 방식으로 UI를 구성.


1. ForEach 기본 구조

ForEach(data, id: \\.self) { item in
    Text(item)
}

매개변수

  1. 데이터 (data)
    • 반복하려는 컬렉션. 배열, 범위, 식별 가능한 데이터 등이 될 수 있음.
  2. 식별자 (id)
    • 각 항목을 고유하게 식별하기 위한 값. (예: id: \\.self 또는 모델의 고유 식별자)
  3. 뷰 클로저
    • 각 항목에 대해 생성할 뷰를 정의하는 클로저.

2. ForEach 사용 예제

배열을 반복하기

struct NamesView: View {
    let names = ["Alice", "Bob", "Charlie"]

    var body: some View {
        ForEach(names, id: \\.self) { name in
            Text(name)
        }
    }
}
Alice
Bob
Charlie
  • `id: \.self`를 사용하면 Swift가 각 항목 자체를 고유 식별자로 사용.
  • 배열의 항목이 Hashable 프로토콜을 준수해야 함.

범위를 반복하기

struct NumbersView: View {
    var body: some View {
        ForEach(1...5, id: \\.self) { number in
            Text("Number \\(number)")
        }
    }
}
Number 1
Number 2
Number 3
Number 4
Number 5
  • 범위(range)를 반복할 때는 숫자 자체가 고유 식별자.

식별 가능한 데이터 모델 사용하기

struct Item: Identifiable {
    let id = UUID()
    let name: String
}

struct ItemsView: View {
    let items = [
        Item(name: "Item 1"),
        Item(name: "Item 2"),
        Item(name: "Item 3")
    ]

    var body: some View {
        ForEach(items) { item in
            Text(item.name)
        }
    }
}
  • 모델이 Identifiable 프로토콜을 준수하면 id 매개변수 생략 가능.
  • SwiftUI는 Identifiable의 id 속성을 자동으로 식별자로 사용하기 때문에.

3. 고유 식별자 설정의 중요성

ForEach에서 항목의 고유 식별자는 필수.

고유 식별자를 지정하지 않으면, SwiftUI는 상태와 애니메이션을 제대로 관리할 수 없게 됨.

ForEach(["Alice", "Bob", "Charlie"]) { name in
    Text(name) // 오류 발생!
}
  • id를 제공하지 않으므로 오류가 발생.

4. State와 함께 사용하기

@State를 사용하여 동적으로 업데이트되는 데이터와 함께 ForEach를 사용할 수 있음.

struct DynamicListView: View {
    @State private var items = ["Item 1", "Item 2", "Item 3"]

    var body: some View {
        VStack {
            ForEach(items, id: \\.self) { item in
                Text(item)
            }

            Button("Add Item") {
                items.append("Item \\(items.count + 1)")
            }
        }
    }
}
  • 버튼을 클릭하면 items 배열에 새로운 항목이 추가.
  • SwiftUI는 ForEach가 참조하는 배열이 업데이트된 것을 감지하고, UI를 다시 렌더링.

5. 중첩된 ForEach

struct NestedForEachView: View {
    let data = [
        ["A", "B", "C"],
        ["1", "2", "3"]
    ]

    var body: some View {
        VStack {
            ForEach(data, id: \\.self) { row in
                HStack {
                    ForEach(row, id: \\.self) { item in
                        Text(item)
                    }
                }
            }
        }
    }
}
A B C
1 2 3

6. 성능 고려

  • ForEach는 뷰를 동적으로 생성하므로, 많은 데이터 항목을 반복할 때 성능이 중요.
  • 데이터가 클 경우, lazy container(예: LazyVStack 또는 LazyHGrid)와 함께 사용하는 것이 효율적.
struct LazyListView: View {
    let numbers = Array(1...1000)

    var body: some View {
        ScrollView {
            LazyVStack {
                ForEach(numbers, id: \\.self) { number in
                    Text("Number \\(number)")
                }
            }
        }
    }
}

7. ForEach와 Group의 차이

  • ForEach는 데이터를 반복하여 개별 뷰를 생성하고, 상태 관리를 지원.
  • 반면, Group은 반복된 뷰를 묶어 그룹화만 하고, 상태를 관리하지 않음.
struct ExampleView: View {
    let items = ["One", "Two", "Three"]

    var body: some View {
        // ForEach는 상태 관리 가능
        ForEach(items, id: \\.self) { item in
            Text(item)
        }

        // Group은 단순 그룹화
        Group {
            Text("One")
            Text("Two")
            Text("Three")
        }
    }
}

8. ForEach 선택 가이드

상황 적합 여부
데이터 항목이 동적으로 추가, 삭제됨 사용 가능
데이터를 기반으로 상태 관리가 필요함 사용 가능
데이터 항목이 고정되어 있고 상태 관리가 불필요함 Group 추천
대량의 데이터로 성능 문제가 발생할 수 있음 LazyVStack, LazyHGrid와 함께 사용

'SwiftUI' 카테고리의 다른 글

[SwiftUI] @ViewBuilder  (0) 2024.05.20
[SwiftUI] AsyncImage in SwiftUI  (0) 2024.05.13
[SwiftUI] NavigationView vs NavigationStack  (0) 2024.05.09
[SwiftUI] SwiftUI의 View Rendering  (0) 2024.05.08
[SwiftUI] ViewModifier, modifier(_:)  (0) 2024.05.03