How to create grid of square items (for example like in iOS Photo Library) with SwiftUI?
I tried this approach but it doesn\'t work:
var body: some
Checkout ZStack based example here
Grid(0...100) { _ in
Rectangle()
.foregroundColor(.blue)
}
Tired of finding many complicated solutions or Github libraries, I have decided to do my own, easy and beautiful Mathematical solution.
var items : [ITEM] = [...YOUR_ITEMS...]
When N is the number of ROWS and 2 is the number of COLUMNS
ForEach
statements, one for columns and one for rows.Into both
ForEach
: (i) current index of ROWS, and (j) current index of COLUMNS
Note: Xcode 11.3.1
var items : [ITEM] = [...YOUR_ITEMS...]
var body: some View {
VStack{
// items.count/2 represent the number of rows
ForEach(0..< items.count/2){ i in
HStack(alignment: .center,spacing: 20){
//2 columns
ForEach(0..<2){ j in
//Show your custom view here
// [(i*2) + j] represent the index of the current item
ProductThumbnailView(product: self.items[(i*2) + j])
}
}
}.padding(.horizontal)
Spacer()
}
}
I think you can use scrollview like this
struct MovieItemView : View {
var body: some View {
VStack {
Image("sky")
.resizable()
.frame(width: 150, height: 200)
VStack {
Text("Movie Title")
.font(.headline)
.fontWeight(.bold)
Text("Category")
.font(.subheadline)
}
}
}
}
struct MoviesView : View {
var body: some View {
VStack(alignment: .leading, spacing: 10){
Text("Now Playing")
.font(.title)
.padding(.leading)
ScrollView {
HStack(spacing: 10) {
MovieItemView()
MovieItemView()
MovieItemView()
MovieItemView()
MovieItemView()
MovieItemView()
}
}
.padding(.leading, 20)
}
}
}
Thinking in SwiftUI, there is a easy way :
struct MyGridView : View {
var body: some View {
List() {
ForEach(0..<8) { _ in
HStack {
ForEach(0..<3) { _ in
Image("orange_color")
.resizable()
.scaledToFit()
}
}
}
}
}
}
SwiftUI enough if you want,you need forgot such as UIColectionView sometimes..
Based on Will's answer i wrapped it all up in a SwiftUI ScrollView. So you can achieve horizontal (in this case) or vertical scrolling.
It's also uses GeometryReader so it is possible to calculate with the screensize.
GeometryReader{ geometry in
.....
Rectangle()
.fill(Color.blue)
.frame(width: geometry.size.width/6, height: geometry.size.width/6, alignment: .center)
}
Here is the a working example:
import SwiftUI
struct MaterialView: View {
var body: some View {
GeometryReader{ geometry in
ScrollView(Axis.Set.horizontal, showsIndicators: true) {
ForEach(0..<2) { _ in
HStack {
ForEach(0..<30) { index in
ZStack{
Rectangle()
.fill(Color.blue)
.frame(width: geometry.size.width/6, height: geometry.size.width/6, alignment: .center)
Text("\(index)")
}
}
}.background(Color.red)
}
}.background(Color.black)
}
}
}
struct MaterialView_Previews: PreviewProvider {
static var previews: some View {
MaterialView()
}
}
We've developed a swift package that provides a fully featured CollectionView for use in SwiftUI.
Find it here: https://github.com/apptekstudios/ASCollectionView
It's designed to be easy to use, but can also make full use of the new UICollectionViewCompositionalLayout for more complex layouts. It supports auto-sizing of cells.
To achieve a grid view you could use it as follows:
import SwiftUI
import ASCollectionView
struct ExampleView: View {
@State var dataExample = (0 ..< 21).map { $0 }
var body: some View
{
ASCollectionView(data: dataExample, dataID: \.self) { item, _ in
Color.blue
.overlay(Text("\(item)"))
}
.layout {
.grid(layoutMode: .adaptive(withMinItemSize: 100),
itemSpacing: 5,
lineSpacing: 5,
itemSize: .absolute(50))
}
}
}
See the demo project for examples of far more complex layouts.