我想知道在视图层级的不同级别中多次调用navigationDestination()
是否可行?我在谷歌上搜索了一下,但我找到的所有示例都是在NavigationStack
中的顶级视图上调用它。我尝试了以下代码。它可以正常工作,但我不确定这是意外还是设计上的。我希望这样编码,因为它有助于组织代码。
struct ID<Value>: Hashable, Equatable {
let uuid: UUID
init() {
uuid = UUID()
}
}
typealias CategoryID = ID<Category>
typealias ItemID = ID<Item>
struct Catalog {
var categories: [Category]
func getCategory(_ categoryID: CategoryID) -> Category? {
return categories.first { $0.id == categoryID }
}
func getItem(_ categoryID: CategoryID, _ itemID: ItemID) -> Item? {
guard let category = getCategory(categoryID) else { return nil }
return category.items.first { $0.id == itemID }
}
}
struct Category: Identifiable {
var id: CategoryID = .init()
var name: String
var items: [Item]
}
struct Item: Identifiable {
var id: ItemID = .init()
var name: String
}
func createTestData() -> Catalog {
let categories = [
Category(name: "Category A", items: [Item(name: "Item a1"), Item(name: "Item a2")]),
Category(name: "Category B", items: [Item(name: "Item b1"), Item(name: "Item b2")])
]
return Catalog(categories: categories)
}
struct ContentView: View {
@State var catalog: Catalog = createTestData()
var body: some View {
NavigationStack {
List {
ForEach(catalog.categories) { category in
NavigationLink(category.name, value: category.id)
}
}
// This is the typical place to make one or multiple calls of navigationDestination().
.navigationDestination(for: CategoryID.self) { categoryID in
CategoryView(categoryID: categoryID, catalog: $catalog)
}
}
}
}
struct CategoryView: View {
let categoryID: CategoryID
@Binding var catalog: Catalog
var body: some View {
if let category = catalog.getCategory(categoryID) {
List {
ForEach(category.items) { item in
NavigationLink(item.name, value: item.id)
}
}
// Q: is it OK to call navigationDestination() here?
.navigationDestination(for: ItemID.self) { itemID in
ItemView(categoryID: categoryID, itemID: itemID, catalog: $catalog)
}
}
}
}
struct ItemView: View {
let categoryID: CategoryID
let itemID: ItemID
@Binding var catalog: Catalog
var body: some View {
if let item = catalog.getItem(categoryID, itemID) {
Text(item.name)
}
}
}
注意代码使用了通用标识符类型,否则SwifUI无法区分
navigationDestination(for: CategoryID)
和navigationDestination(for: ItemID)
。