Я думаю, что Image
внутри вашего Grid
может быть причиной ваших проблем. Вы можете использовать GeomteryReader
для установки максимальной ширины изображения. Поскольку у меня нет изображения, которое вы используете, я заменил его на RoundedRectangle
.
В коде ниже вы можете видеть, что я устанавливаю кадр RoundedRectangle
и присваиваю ему maxWidth
. Я также рассчитываю и устанавливаю динамическую высоту на RoundedRectangle
.
Нам нужно установить кадр VStack
, содержащий Grid
. Так как мы знаем высоту строки в Grid
, мы можем вычислить высоту двух строк и установить содержащую VStack
на эту высоту.
Приведенный ниже код дает следующий вывод:

struct ContentView: View {
var body: some View {
GeometryReader { gr in
VStack {
HStack {
Text("Explore More")
.font(.headline)
.foregroundColor(.black)
.padding(.leading, 20)
Spacer()
}
VStack(spacing: 0) {
Grid(leftTitle: "Desert", rightTitle: "Kids")
Grid(leftTitle: "Stripes", rightTitle: "Pastels")
}.frame(maxWidth: .infinity, maxHeight: gridHeight(gr, count: 2))
.background(Color.red)
}.background(Color.orange)
}
}
}
// MARK: - Grid
struct Grid: View {
let leftTitle: String
let rightTitle: String
@State private var showLeft = false
@State private var showRight = false
var body: some View {
GeometryReader { gr in
return HStack(spacing: 12) {
Button(action: { self.showLeft = true }) {
ZStack {
RoundedRectangle(cornerRadius: 20)
.frame(maxWidth: width(gr), maxHeight: height(gr))
Text(self.leftTitle)
.foregroundColor(.black)
.font(.subheadline)
}
}
Button(action: { self.showRight = true }) {
ZStack {
RoundedRectangle(cornerRadius: 20)
.frame(maxWidth: width(gr), maxHeight: height(gr))
Text(self.rightTitle)
.foregroundColor(.black)
.font(.subheadline)
}
}
}.frame(width: gr.size.width, height: height(gr) + 24, alignment: .center)
}
}
}
let horizontalPadding: CGFloat = 20 + 20 + 12 // 20 for each side and 12 in the middle
func gridHeight(_ gr: GeometryProxy, count: Int) -> CGFloat {
return CGFloat(count) * (height(gr) + 24)
}
func height(_ gr: GeometryProxy) -> CGFloat {
return (gr.size.width - horizontalPadding) / 3
}
func width(_ gr: GeometryProxy) -> CGFloat {
return (gr.size.width - horizontalPadding) / 2
}
Указанные выше вспомогательные функции можно настроить так, чтобы они принималифактическое заполнение, которое вы планируете использовать, или для придания желаемой высоты и ширины изображения. В конечном счете, нет жестко заданных высот, поэтому это должно учитываться при любом размере экрана.