Reputation: 1603
How do I implement a collection view (that is, rectangles arranged in a grid) in SwiftUI?
I've tried ForEach-ing over a range of values, then using the counter as an index for an Array but have had numerous problems so are looking for a different way to achieve a collection view.
The cells to wrap over multiple rows. I have a SegmentedControl
which is used to set how many cells to squeeze on one row.
Here is what I have:
VStack { // Multiple rows
ForEach((0..<requiredRows).identified(by: \.self)) { row in // Iterate over (previously calculated) required row count
HStack(spacing: 50)) { // Row
ForEach((0..<self.maximumOnXAxis).identified(by: \.self)) { cell in // Iterate over available cells
MyView(
width: calculatedSize,
height: calculatedSize / 2.0,
colour: Color(
red: lst[row * self.maximumOnXAxis][0],
green: lst[row * self.maximumOnXAxis][1],
blue: lst[row * self.maximumOnXAxis][2]
)
)
}
}
}
And all of the above is inside a ScrollView.
The current problem is a 'Could not type check in reasonable time ...', which happened after I add the colour: Colour(...)
parameter to MyView
.
Upvotes: 3
Views: 8250
Reputation: 1654
Maybe this is what you are looking for : https://github.com/pietropizzi/GridStack
The only missing feature is that you cannot do "masonry" like layout
Upvotes: 1
Reputation: 559
SwiftUI does support a ScrollView
which you can use to present collections, although you would have to manage your own grids. The GeometryReader
method might be helpful, it allows you to easily scale the "cells" to the width and length of the parent view.
For reference, I've created a simple horizontal scroll view. You can use this same logic to create a grid view:
import SwiftUI
import PlaygroundSupport
struct MyView : View {
let items: [String] = ["1", "2", "3", "4", "5"]
var body : some View {
GeometryReader { geometry in
ScrollView {
HStack {
ForEach(self.items.identified(by: \.self)) { row in
Text(row)
.padding(geometry.size.width / 5)
.background(Color.green)
}
}
}.background(Color.white)
}
.padding()
.background(Color.red)
}
}
let vc = UIHostingController(rootView: MyView())
PlaygroundPage.current.liveView = vc
Upvotes: 3