I have to do a collectionView with image, two texts and two buttons. I'd like to increase padding of VStack inside LazyVGrid but couldn't achieve it. Could you please help me to figure out what's wrong?
let columns = Array(repeating: GridItem(.flexible(), spacing: 20, alignment: .center), count: 2)
var body: some View {
NavigationView {
ScrollView {
LazyVGrid(columns: columns, spacing: 20, content: {
ForEach(data, id:\.self) { item in
VStack(alignment: .leading, spacing: 10) {
Image("\(item.image)")
.resizable()
.frame(width: 150, height: 200)
.padding(4)
.cornerRadius(10)
Text(item.name)
Text(item.price)
HStack(spacing: 15) {
Button(action: {}) {
HStack {
Image(systemName: "cart")
Text("В Корзину")
.fixedSize(horizontal: true, vertical: false)
}
.padding(10)
.background(Color.blue)
.foregroundColor(Color.white)
.cornerRadius(10)
}
Button(action: {}) {
Image(systemName: "heart")
}
.padding(10)
.background(Color.white)
.clipShape(Rectangle())
.foregroundColor(.blue)
.cornerRadius(10)
}
} .foregroundColor(Color.black)
.background(Color.red)
.cornerRadius(25)
.padding(15)
}
}).padding(15)
}
}
}
}
CodePudding user response:
Welcome to Stack Overflow! Please take the tour and see: How do I ask a good question? and How to create a Minimal, Reproducible Example.
You had a bunch of issues here, and they were each little things that added up to you having significant issues with your view. The first thing I did was change your column
to .fixed()
. This may or may not be what you wanted, but it seemed like you wanted equal sized grid items.
I also got the images under control by setting .aspectRatio(contentMode: .fit)
and a .frame(height: 140)
on them.
Next, I removed as many .padding()
as I could. I also put more of VStacks
and HStacks
in to keep things in logical order. By the time I was done this, it seemed that the issue was the two buttons on the bottom in the HStack
. There simply wasn't room, so I moved the favorite
button.
My overall advice. Set frames, but only one direction if possible. Think in logical groupings. Make sure different views fit. Manage your images with a frame and aspect ratios.
Last thing: With questions on how to work with views like you had, please give a minimal, reproducible example to work with. I had to make a data struct, and use SF Symbols so it works on everyone else's machine. You are asking the question, so that is work you should be doing for this taking their time to help. You will get more answers that way.
struct GridPaddingView: View {
let dataArray: [Datum] = [
Datum(name: "square", image: "square.and.arrow.up.trianglebadge.exclamationmark", price: "$1.00"),
Datum(name: "trash", image: "trash.slash.fill", price: "$1.00"),
Datum(name: "folder", image: "folder.badge.minus", price: "$1.00"),
Datum(name: "external drive", image: "externaldrive.fill.badge.minus", price: "$1.00"),
Datum(name: "doc", image: "doc.fill.badge.plus", price: "$1.00"),
Datum(name: "calendar", image: "calendar.day.timeline.leading", price: "$1.00")
]
let columns = Array(repeating: GridItem(.fixed(180), spacing: 10), count: 2)
var body: some View {
NavigationView {
ScrollView {
LazyVGrid(columns: columns) {
ForEach(dataArray) { item in
VStack(alignment: .leading) {
VStack(alignment: .leading) {
Image(systemName: item.image)
.resizable()
.aspectRatio(contentMode: .fit)
.cornerRadius(10)
.frame(height: 140)
HStack {
VStack(alignment: .leading) {
Text(item.name)
.fixedSize(horizontal: false, vertical: true)
Text(item.price)
}
Spacer()
Button(action: {}) {
Image(systemName: "heart")
}
.padding(10)
.background(Color.white)
.foregroundColor(.blue)
.cornerRadius(10)
}
}
.padding(5)
Spacer()
HStack() {
Spacer()
Button(action: {}) {
HStack {
Image(systemName: "cart")
Text("В Корзину")
.fixedSize(horizontal: true, vertical: false)
}
.padding()
.background(Color.blue)
.foregroundColor(Color.white)
.cornerRadius(10)
}
Spacer()
}
}
.padding(10)
.frame(height: 300)
.background(Color.red)
.cornerRadius(25)
}
}
}
}
}
}
struct Datum: Identifiable {
let id = UUID()
let name: String
let image: String
let price: String
}