Reputation: 1413
I have defined a few (up to many) different SwiftUI Views:
ViewA(), ViewB(), ViewC() .. ViewN()
Each View contains a specific information that I want to present depending on the choice made by the user..
I created a Hashable, Identifiable list of items and I want to link each item to one specific view. But I can not seem to overcome the errors..
Here is a specific example of exactly what I am trying to do:
//Country Definitions:
import Foundation
import Combine
import SwiftUI
let Countries = [
CountryModel(countryID: "US", countryName: "United States", countryView: USAView() )
CountryModel(countryID: "UK", countryName: "United Kingdom", countryView: UKView() )
]
struct CountryModel: Identifiable, Hashable {
let id:UUID
let countryID:String
let countryName:String
let countryView:View //I have tried AnyView here, different issues, still no go...
init(countryID:String, countryName:String, countryView:View) {
self.id = UUID();
self.countryID = countryID
self.countryName = countryName
self.countryView = countryView
}
}
How it is planned to be used in theory is in a NavigationView / NavigationLink as such:
struct ContentView: View {
var body: some View {
NavigationView {
ForEach(Countries) { thisCoutry in
NavigationLink(destination: thisCoutry.countryView) { //Also tried forcing as! View, no good
MyItemCell(itemName: thisCoutry.countryName, itemDesc: thisCoutry.countryID)
}
}
}
}
}
(MyItemCell is just a View to format the name and ID of the item)..
Thus far, trying to use "View", I get the errors:
Protocol 'View' can only be used as a generic constraint because it has Self or associated type requirements
and something about not conforming to Equatable. When I add Equatable and have it add the stub with return true, no help...
struct CountryModel: Hashable, Identifiable, Equatable {
static func == (lhs: CountryModel, rhs: CountryModel) -> Bool {
return true
}
I also get an error proclaiming that this does not conform to Hashable, so I tried taking that out and still no go..
Any ideas greatly appreciated. Trying to avoid a long list of Nav Links as SwiftUI seems to get funky at/around/after 10 or so and I have to start Grouping, or being otherwise more creative...
struct ContentView: View {
var body: some View {
VStack{
NavigationView {
NavigationLink(destination: ViewA()) {
MyItemCell(itemName: "United States", itemDesc: "USA")
}
NavigationLink(destination: ViewB()) {
MyItemCell(itemName: "United Kingdom", itemDesc: "UK")
}
}
}
}
}
Upvotes: 3
Views: 320
Reputation: 257719
You can go with AnyView
type erasure wrapper (but it should be not only declared in model but used explicitly when created - casting does not work here, this I assume was the origin of errors):
let Countries = [
CountryModel(countryID: "US", countryName: "United States",
countryView: AnyView(USAView()) ) // << here !!
CountryModel(countryID: "UK", countryName: "United Kingdom",
countryView: AnyView(UKView()) )
]
struct CountryModel: Identifiable, Hashable {
let id:UUID
let countryID:String
let countryName:String
let countryView:AnyView
init(countryID:String, countryName:String, countryView:View) {
self.id = UUID();
self.countryID = countryID
self.countryName = countryName
self.countryView = countryView
}
}
Upvotes: 1