I am trying to implement a generic View that can display an horizontally scrollable paged list of items, given a collection.
The non generic version works smoothly, and if i try to abstract it
import SwiftUI
struct PagedListView<Element, Content> where Element: Hashable, Content: View {
/// The array of items to distribute along the various pages of the list
var data: Array<Element>
var itemsPerPage: Int
/// Build the view for a single item of a page
public var content: (Element) -> Content
private var numPages: Int {
return Int(ceil(Double(data.count) / Double(itemsPerPage)))
}
private func rangeForPage(_ page: Int) -> Range<Int> {
return (page*itemsPerPage)..<min(data.count, page*itemsPerPage+itemsPerPage)
}
var body: some View {
TabView {
ForEach(0..<numPages, id: \.self) { pageNum in
page(pageNum)
}
.padding(.bottom, 30)
}
.tabViewStyle(.page)
}
@ViewBuilder
private func page(_ page: Int) -> some View {
VStack(alignment: .leading, spacing: 0) {
// TODO: pass a keypath to the view, to define the id instead of \.self, like List
ForEach(data[rangeForPage(page)], id: \.self) { itemData in
content(itemData)
}
Spacer().padding(0)
}
.frame(maxWidth: .infinity, alignment: .leading)
}
}
This compiles, but usage
struct UsageView: View {
var body: some View {
VStack { // *** COMPILE ERROR HERE ***
PagedListView(data: [0,1,2,3,4,5,6,7], itemsPerPage: 3) { item in
Text("Item: \(item)")
}
}
}
}
triggers the following error
Static method 'buildBlock' requires that 'PagedListView<Int, Text>' conform to 'View'
on the containing View, I can't grasp what is wrong.
I am fairly sure it has to to with the generic constraitns on protocols but i can't go by exclusions or it does not compile at all How can i understand what the issue is here?
The error message is describing exactly what is wrong: PagedListView
doesn't conform to the protocol View
. Just conform to it in your declaration:
struct PagedListView<Element, Content>: View where Element: Hashable, Content: View {
Notice that we added :View
before the where
clause, to ensure that the PagedListView
conforms to the protocol View
.