J
[SwiftUI] ForEach in SwiftUI 본문
ForEach in SwiftUI
ForEach는 SwiftUI에서 컬렉션의 요소를 반복(iterate)하여 동적으로 뷰를 생성할 때 사용하는 뷰.
SwiftUI는 선언적 UI 프레임워크이므로 반복문(for-in) 대신 ForEach를 사용하여 간결하고 효율적인 방식으로 UI를 구성.
1. ForEach 기본 구조
ForEach(data, id: \\.self) { item in
Text(item)
}
매개변수
- 데이터 (data)
- 반복하려는 컬렉션. 배열, 범위, 식별 가능한 데이터 등이 될 수 있음.
- 식별자 (id)
- 각 항목을 고유하게 식별하기 위한 값. (예: id: \\.self 또는 모델의 고유 식별자)
- 뷰 클로저
- 각 항목에 대해 생성할 뷰를 정의하는 클로저.
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 |