I'm trying to display an image in the middle of the screen:
struct ContentView: View {
let items = ["A", "B", "C", "D", "E", "F", "G"]
var body: some View{
VStack {
ForEach(items, id: \.self) { item in
Text(item)
}
Spacer() // 3.
GeometryReader { geometry in
Image("image-300x1200")
.resizable() // 1.
}
Button("Action") {}
}
}
}
I want the image to:
- Fill the full width of the screen, and
- Vertically if height is more than available space, crop top and bottom to fill available space without push the other views above and below the image beyond screen, and
- If the image height is less than available height, stick it to the bottom view which is the button
So far I think I've achieved 1 and 2, just not sure what modifies I need for 2:
So the image is resized without keeping aspect ratio. If I add scaledToFill() after resizable() it goes beyond the bottom of screen:
Then I thought about using the space provided by geometry reader, like adding the following:
.aspectRatio(geometry.size.width / geometry.size.height, contentMode: .fill)
But it still doesn't work as it doesn't crop.


You can do:
.aspectRatio(contentMode: .fill)makes the image expand to fill the entire available width. Note that we do not want it to also expand vertically to fill the entire available height, hence thefixedSizemodifier.Then,
maxHeight: geometry.size.heightgives it a frame with maximum available height. Note that when the height is too large, the image will exceed this frame, so it also needs to beclipped().alignment: .bottomso that the image stays at the bottom of the frame when the height is less than the available height.