I am working on a SwiftUI view that displays an image fetched from a URL using AsyncImage. I want the image to fill the entire screen, and I have a row of buttons overlaid at the bottom of the image within a ZStack. However, when I set the AsyncImage's contentMode to .fill, the buttons are not visible. Changing the contentMode to .fit makes the buttons appear, but the image no longer fills the entire screen as desired.
Here is the code snippet demonstrating the issue:
import SwiftUI
struct ImageViewTest: View {
private let wallpaperPath = "https://w.wallhaven.cc/full/7p/wallhaven-7pmj9o.jpg"
var body: some View {
ZStack(alignment: .center) {
AsyncImage(url: URL(string: wallpaperPath)) { phase in
switch phase {
case .empty:
ProgressView()
case .failure:
Text("Failed to fetch image")
case .success(let image):
image
.resizable()
.aspectRatio(contentMode: .fill) // Changing this to .fit shows the buttons
.clipped()
@unknown default:
fatalError()
}
}
.ignoresSafeArea(.all)
VStack {
Spacer()
HStack {
Button(action: {}) {
Image(systemName: "square.and.arrow.down")
.foregroundStyle(.blue)
}
Spacer()
Button(action: {}) {
Image(systemName: "heart")
.foregroundStyle(.blue)
}
Spacer()
Button(action: {}) {
Image(systemName: "arrow.down.circle")
.foregroundStyle(.blue)
}
}
.padding()
.background(.ultraThinMaterial)
.cornerRadius(10)
}
}
}
}
#Preview {
ImageViewTest()
}
My goal is to have the image fill the entire screen while keeping the buttons visible at the bottom. I would appreciate any suggestions or insights into what might be causing the buttons to be covered when using .fill for the contentMode.
- Changing the contentMode from .fill to .fit, which shows the buttons but does not meet the requirement of the image filling the screen.
That's because the image caused the
ZStack
'swidth
to overflow the screen and you need to prevent this somehow.iOS 17
If you are targeting iOS 17 or later, adding the following modifier to the
AsyncImage
would be enough:iOS 13 or later
One way is to use
background
modifier on theVStack
instead of usingZStack
like:Both of the above methods would cause the view appear like this: