I want to achieve a specific design with 7 pictures. The 7 pictures consist of 5 squares (800x800px original) and 2 rectangle (400x200px original). The end goal should look like this example:
It should be 3 rows of pictures, row 1 consists of 3 squares, where on is about a third of the row, row 2 has a rectangle and a square and the last row just has a single rectangle. The Problem I'm facing is that when I add the view to the parent, I get that outcome:
To achieve this layout I tried to use a combination of VStacks and HStack and tried to calculate the width of the pictures using about 1/3 of the view with a GeometryReader.
import SwiftUI
struct OverviewTiles: View {
var body: some View {
// TODO: There will be different designs so be sure to look out for that
GeometryReader { geo in
let size = geo.size.width * 0.66
VStack(spacing: 16) {
HStack(spacing: 16) {
Image("tiles_square")
.resizable()
.scaledToFit()
.frame(width: size)
VStack(spacing: 16) {
Image("tiles_square")
.resizable()
.scaledToFit()
Image("tiles_square")
.resizable()
.scaledToFit()
}
}
HStack(spacing: 16) {
Image("tiles_landscape")
.resizable()
.scaledToFit()
.frame(width: size)
Image("tiles_square")
.resizable()
.scaledToFit()
}
Image("tiles_landscape")
.resizable()
.scaledToFit()
}
.frame(maxWidth: .infinity, maxHeight: .infinity)
}
}
}
The View itself is instantiated inside a ScrollView. I'm relatively new to SwiftUI and I would like to know if this is even the correct approach. Ultimately I like to have this element react correctly to orientation changes, though maybe the order of the images should be changed then. So, is using GeometryReader the correct way or are there better ways to achieve this?
Thank you very much, for helping out.
When I tried your code, it looks quite like the first screenshot (your target layout). However, when you wrap it all in a ScrollView
then it looks like the second screenshot (broken).
Views inside a ScrollView
are shown at their ideal size and the ideal size of a GeometryReader
is very small. So you need to make sure that the ScrollView
is nested inside the GeometryReader
, not the other way around:
var body: some View {
GeometryReader { geo in
let size = geo.size.width * 0.66
ScrollView {
VStack(spacing: 16) {
// ...
}
.frame(maxWidth: .infinity, maxHeight: .infinity)
}
}
}