Home > database >  How can the Compiler automatically infer the Types of a Multi Generic Type SwiftUI View?
How can the Compiler automatically infer the Types of a Multi Generic Type SwiftUI View?

Time:12-17

Context

I have a generic SwiftUI View that has two generic types. The first one needs to be specified manually while the second one could be inferred by the content passed to its Initialiser.

However, the Compiler forces me to specify both generic types manually when using the View. This results in very complex definitions like in the example below.


Code

protocol Entity {
    static var name: String { get }
}

struct EntityView<E: Entity, Content: View>: View {
    private let content: Content
    
    init(@ViewBuilder content: () -> Content) {
        self.content = content()
    }
    
    var body: some View {
        VStack {
            Text(E.name)

            content
        }
    }
}

struct ContentView {
    var body: some View {
        EntityView<Profile, TupleView<(HStack<EmptyView>, HStack<EmptyView>, Text)>> { // This is obviously not clean to define manually.
            HStack { ... }

            HStack { ... }

            Text("Hello World")
        }
    }
}


Question

Is there any "cleaner" way to achieve this functionality? Is it possible to somehow only define the generic type that cannot be inferred?

CodePudding user response:

Swift needs to either infer all the type parameters, or all the type parameters have to be specified explicitly.

One place from which Swift infers type parameters is the parameter list. Therefore, to make it "infer" E as well, add a parameter with E.Type in it.

init(_ type: E.Type, @ViewBuilder content: () -> Content) {
    self.content = content()
}

Then, when using the view, pass Profile.self:

EntityView(Profile.self) {
    ...
}
  • Related