Reputation: 15872
I've got a protocol with two classes that implement it:
protocol GalleryItem {
func toView() -> AnyView
}
extension Class1:GalleryItem {
func toView() -> AnyView {
...
}
}
extension Class2:GalleryItem {
func toView() -> AnyView {
...
}
}
An array:
var array:[GalleryItem] = [Class1(), Class2()]
Now if I try to use that array in a ForEach:
ForEach(array, id: \.self) { item in
item.toView()
}
I get this error:
Value of protocol type 'GalleryItem' cannot conform to 'Hashable'; only struct/enum/class types can conform to protocols
Does that mean I can't have a protocol array like this passed to ForEach? How else would I accomplish this?
Upvotes: 2
Views: 729
Reputation: 3353
Ok, let's make it work.
In your case, the compiler expects parameter \.self
to be Hashable
and this parameter is an object of your protocol GalleryItem
.
To solve this, we can add a requirement to the protocol that can provide an \.id
. For example:
protocol GalleryItem {
func toView() -> AnyView
var id: Int { get } // could be any `Hashable` type
}
And then, instead of using \.self
in the ForEach as identifier, we can use \.id
as an identifier:
ForEach(items, id: \.id) { item in
item.toView()
}
The naming and the type here are pretty much up to you. \.id
and Int
are used as an example.
Upvotes: 8