Ok I was able to come up with a solution, however becase of my limited knowledge with generics I ended up using
AnyView instead of the actual data type which takes a hit on performance.
Code Block swiftimport SwiftUI |
import PlaygroundSupport |
|
protocol DataSourceView { |
|
associatedtype Data |
associatedtype Container: View |
|
static func make<Content: View>(@ViewBuilder content: @escaping (Data) -> Content) -> Container |
} |
|
struct SimpleData: Hashable { |
let title: String |
} |
|
struct ListView<DataSource: DataSourceView>: View where DataSource.Data == [SimpleData] { |
|
var body: some View { |
|
DataSource.make { items in |
List { |
ForEach(items, id: \.self) { item in |
Text(item.title) |
} |
} |
} |
} |
} |
|
struct RichDataSource: DataSourceView { |
|
static func make<Content: View>(content: @escaping ([SimpleData]) -> Content) -> AnyView { |
AnyView(Container(content: content)) |
} |
|
struct Container<Content: View>: View { |
|
let content: ([SimpleData]) -> Content |
@State private var richDataItems = (1...10).map { $0 } |
|
var body: some View { |
content(richDataItems.map { SimpleData(title: "Title: \($0)") }) |
} |
} |
} |
|
PlaygroundPage.current.setLiveView(ListView<RichDataSource>()) |
The following won't work which kind of what I would like to do. If anyone has a solution for this could you please provide an explanation, I would really appreciate it, again I have limited generics knowledge.
Code Block swiftstatic func make<Content: View>(content: @escaping ([SimpleData]) -> Content) -> Container<Content> { |
Container(content: content) |
} |