Div
Div

Reputation: 1603

Implement a collection view SwiftUI

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.

Example of desired effect: Collection View Example

Upvotes: 3

Views: 8250

Answers (2)

Manel
Manel

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

MoFlo
MoFlo

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

Related Questions