Consider the following code,
import SwiftUI
class Product: Identifiable {
let id = UUID()
let title: String
init(title: String) {
self.title = title
}
}
struct ContentView: View {
let products: [Product]
init(products: [Product]) {
self.products = products
}
var body: some View {
NavigationStack {
List(self.products) { product in
NavigationLink(product.title, value: product)
// compiler: "product has to conform to Hashable"
}
.navigationDestination(for: Product.self) { product in
ProductDetailView(product: product)
}
}
}
}
struct ProductDetailView: View {
let product: Product
init(product: Product) {
self.product = product
}
var body: some View {
Text(product.title)
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView(
products: [
Product(title: "Frisbee"),
Product(title: "Bicycle")
])
}
}
The compiler so far claims that Product
has to conform to Hashable. I want to try to avoid slapping Hashable to the Product just to satisfy this particular use case. Is there any other way I could "in-line" tell the NavigationStack construct to consider the ID for hashing, for example? Similar to a ForEach where I can also tell the view which property to consider the id of each item to keep track of it.
I could, for example, instead of having the [Product]
array, a Dictionary of [Product:ID = Product]
, but I still wouldn't know how to pass that to the NavigationLink
or .navigationDestination
since at this point I'd still end up with having only a Product
which again won't satisfy Hashable ofc.
// edit: Also decorating my Product with something like NavigatingProduct: Hashable
wouldn't work I guess because of bindings later…
Having said this, why is there a need for Hashable altogether? Does SwiftUI do some serialization behind to build the breadcrumb for example, or keep a map of hashes to entities?
Thanks for your help!