Skip to content

Instantly share code, notes, and snippets.

@Gujci
Last active October 14, 2019 15:24
Show Gist options
  • Save Gujci/f0bc8bef3d0b9523144b92648db2fc45 to your computer and use it in GitHub Desktop.
Save Gujci/f0bc8bef3d0b9523144b92648db2fc45 to your computer and use it in GitHub Desktop.
Simple grid implementation based on the `ForEach` and `Stack` interfaces
struct Grid<Data: RandomAccessCollection, Content: View>: View, DynamicViewContent where Data.Index == Int {
public var data: Data
public var colCount: Int
public var alignment: HorizontalAlignment
public var spacing: CGFloat
private var render: (Data.Element) -> Content
private func sliceRange(at row: Data.Index) -> Range<Data.Index> {
(row * colCount)..<min((row + 1) * colCount, data.count)
}
public init(by count: Int, of data: Data,
alignment: HorizontalAlignment = .leading, spacing: CGFloat = 0,
@ViewBuilder content: @escaping (Data.Element) -> Content) {
colCount = count
self.data = data
self.spacing = spacing
self.alignment = alignment
render = content
}
var body: some View {
VStack(alignment: self.alignment, spacing: self.spacing) {
ForEach(0..<Int(ceil(Double(self.data.count) / Double(self.colCount)))) { rowIndex in
HStack(spacing: self.spacing) {
ForEach(self.sliceRange(at: rowIndex)) { index in
self.render(self.data[index])
}
}
}
}
}
}
@Gujci
Copy link
Author

Gujci commented Oct 14, 2019

Set .frame(minWidth: 0, maxWidth: .infinity) in the builder if you want full available width for a cell

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment