struct NavigationView: View {
let number: Int
var body: some View {
Text("\(number) NavigationView")
}
init(number: Int) {
self.number = number
print("\(number) NavigationView created")
}
}
struct ContentView: View {
var body: some View {
NavigationStack {
List(1..<51) { num in
NavigationLink("\(num) NavigationView") {
NavigationView(number: num)
}
}
}
}
}
위와 같이 생성될 때 문장을 출력하는 NavigationView
를 만들어서 List 안에 NavigationLink를 나타냈다. build를 통해 아래의 터미널 창을 확인할 수 있다.
위를 보면 알 수 있다싶이, View에 들어가지 않아도 build됨과 동시에 View가 생성된다. 그리고 List 안의 NavigationLink의 경우 실제 개수와 달리 반복되거나 스크롤 될 때 업데이트되는 등의 현상이 나타난다.
이는 swift, swiftui에서 dynamic data를 다룰 때 일어나는 현상이라고 한다.
더 나은 Navigation을 위해선 값과 이동하는 목적지를 구분해야 한다.
그러기 위해선,
1. NavigationLink에 Hashable을 만족하는 값(Int, String, Date, URL, arrays, and dictionaries)을 설정한다.
2. data를 전달받았을 때 무엇을 해야 할지 .navigationDestination()
modifier에 설정한다.
예:
NavigationStack {
List(0..<100) { i in
NavigationLink("Select \(i)", value: i)
}
.navigationDestination(for: Int.self) { selection in
Text("You selected \(selection)")
}
}
💡 struct의 경우 모든 속성이 Hashable을 준수한다면 Hashable 프로토콜을 지정할 수 있다.
struct Person: Hashable {
var id = UUID()
var name: String
}
struct ContentView: View {
var body: some View {
NavigationStack {
List(1..<51) { num in
NavigationLink("\(num)", value: num)
.navigationDestination(for: Int.self, destination: { selection in
Text("You selected \(selection)")
})
.navigationDestination(for: Person.self, destination: { person in
Text("You selected \(person)")
})
}
}
}
}