Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Protocol 'View' can only be used as a generic constraint because it has Self or associated type requirements

Tags:

ios

swift

swiftui

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) {
    ...
        }
   }
}
like image 338
Jon Reed Avatar asked Jun 17 '19 21:06

Jon Reed


People also ask

Can only be used as a generic constraint because it has self or associated?

Protocol 'Equatable' can only be used as a generic constraint because it has Self or associated type requirements.

What are generic protocols?

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.

What is generic constraints in Swift?

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.

What is associated type in Swift?

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.


1 Answers

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)
}
like image 171
Jumhyn Avatar answered Sep 28 '22 08:09

Jumhyn