I'm trying to pass in a destination View Struct to another view, but the code won't compile.
I want to pass in some struct that conforms to the view protocol, so it can be used in a navigation button destination, but I can't seem to get it to compile. I've tried setting the type of destination to _View as well. Any suggestions are much appreciated.
struct AnimatingCard : View {
var title, subtitle : String
var color : Color
var destination : View
init(title : String, subtitle: String, color: Color, destination : View){
self.title = title
self.subtitle = subtitle
self.color = color
self.destination = destination
}
var body: some View {
NavigationButton(destination: destination) {
...
}
}
}
Protocol 'Equatable' can only be used as a generic constraint because it has Self or associated type requirements.
Making a Protocol Generic. There are two ways to create a generic protocol - either by defining an abstract associatedtype or the use of Self (with a capital S). The use of Self or associatedtype is what we like to call "associated types". This is because they are only associated with the protocol they are defined in.
Generics in Swift allows you to write generic and reusable code, avoiding duplication. A generic type or function creates constraints for the current scope, requiring input values to conform to these requirements.
An associated type gives a placeholder name to a type that's used as part of the protocol. The actual type to use for that associated type isn't specified until the protocol is adopted. Associated types are specified with the associatedtype keyword.
If there’s no common concrete type that all the views used in destination
will be, you should use the AnyView
struct to obtain a type-erased concrete View
conforming object.
ETA:
AnyView
has an initializer declared as init<V>(_ view: V) where V : View
, so wherever you were creating your AnimatingCard
before you should now write:
AnimatingCard(title: title, subtitle: subtitle, color: color, destination: AnyView(view))
Alternatively, you could make AnimatingCard
's initializer generic over all View
-conforming types and do the AnyView
conversion inside the initializer, like this:
init<V>(title : String, subtitle: String, color: Color, destination : V) where V: View {
self.title = title
self.subtitle = subtitle
self.color = color
self.destination = AnyView(destination)
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With