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 View {
List(cellModels) { _ in
Color.orange.frame(width: 100, height: 100)
}
}
List still has UITableView style:
One of the possible solutions is to wrap your UICollectionView into UIViewRepresentable. See Combining and Creating Views SwiftUI Tutorial, where they wrap the MKMapView as an example.
By now there isn’t an equivalent of UICollectionView in the SwiftUI and there’s no plan for it yet. See a discussion under that tweet.
To get more details check the Integrating SwiftUI WWDC video (~8:08).
QGrid is a small library I've created that uses the same approach as SwiftUI's List view, by computing its cells on demand from an underlying collection of identified data:
In its simplest form, QGrid can be used with just this 1 line of code within the body of your View, assuming you already have a custom cell view:
struct PeopleView: View {
var body: some View {
QGrid(Storage.people, columns: 3) { GridCell(person: $0) }
}
}
struct GridCell: View {
var person: Person
var body: some View {
VStack() {
Image(person.imageName).resizable().scaledToFit()
Text(person.firstName).font(.headline).color(.white)
Text(person.lastName).font(.headline).color(.white)
}
}
}
You can also customize the default layout configuration:
struct PeopleView: View {
var body: some View {
QGrid(Storage.people,
columns: 3,
columnsInLandscape: 4,
vSpacing: 50,
hSpacing: 20,
vPadding: 100,
hPadding: 20) { person in
GridCell(person: person)
}
}
}
Please refer to demo GIF and test app within GitHub repo:
Try using a VStack and HStack
var body: some View {
GeometryReader { geometry in
VStack {
ForEach(1...3) {_ in
HStack {
Color.orange.frame(width: 100, height: 100)
Color.orange.frame(width: 100, height: 100)
Color.orange.frame(width: 100, height: 100)
}.frame(width: geometry.size.width, height: 100)
}
}
}
}
You can wrap in a ScrollView if you want scrolling
I’ve written a small component called 📱GridStack that makes a grid that adjusts to the available width. Even when that changes dynamically like when you rotate an iPad.
https://github.com/pietropizzi/GridStack
The essentials of that implementation are similar to what others have replied here (so HStacks inside a VStack) with the difference that it figures out the width depending on the available width and a configuration you pass it.
- With
minCellWidthyou define the smallest width you want your item in the grid should have - With
spacingyou define the space between the items in the grid.
e.g.
GridStack(
minCellWidth: 320,
spacing: 15,
numItems: yourItems.count
) { index, cellWidth in
YourItemView(item: yourItems[index]).frame(width: cellWidth)
}
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)
}
}
}
来源:https://stackoverflow.com/questions/56466306/uicollectionview-and-swiftui


