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 swift| import 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 swift| static func make<Content: View>(content: @escaping ([SimpleData]) -> Content) -> Container<Content> { |
| Container(content: content) |
| } |