Consider this 400x800 image:
I would expect the background image in the following code to fill the entire screen:
struct ContentView: View {
var body: some View {
VStack {
}
.frame(maxWidth: .infinity, maxHeight: .infinity)
.background {
Image(.background)
.resizable()
.scaledToFill()
.ignoresSafeArea()
}
}
}
But there's a small gap in the bottom:
Swapping the order of scaledToFill
and ignoresSafeArea
fills this gap:
Image(.background)
.resizable()
.ignoresSafeArea()
.scaledToFill()
Why?
Ignoring specific edges is more problematic:
struct ContentView: View {
var body: some View {
VStack {
}
.statusBarHidden()
.frame(maxWidth: .infinity, maxHeight: .infinity)
.border(.black)
.background {
Image(.background)
.resizable()
.ignoresSafeArea(edges: .top)
.scaledToFill()
}
}
}
My solution here was to use the Image
as an overlay
of a Rectangle
.
Rectangle()
.overlay {
Image(.background)
.resizable()
.scaledToFill()
}
.clipped()
.ignoresSafeArea(edges: .top)
Is there a better way to achieve this?
I wonder if someone from SwiftUI Team could help me to better undestand Image
behavior regardless ignoresSafeArea
.
When you do this:
Image(.background)
.resizable()
.scaledToFill()
.ignoresSafeArea()
You're telling SwiftUI that the image can be resized, and you want to scale it to fill its parent, so SwiftUI scales the image. However, at this point, SwiftUI doesn't know that the image can ignore the safe areas, so the parent view at that point isn't ignoring safe areas. That's why you get the white bit at the bottom.
I took your image and added a red border and yellow squares in the corners so I could see where the image was stretched/resized and positioned. With the code above, you get this:
So you can see it was resized to fit inside the parent view, and doesn't ignore the safe areas.
For your needs, just remove the .scaledToFill()
modifier, you don't need it:
Image(.background)
.resizable()
.ignoresSafeArea()
This yields:
If your ultimate need is to get that last image with just the white bit at the bottom, the fix again is to remove the scaling:
Image(.background)
.resizable()
.ignoresSafeArea(edges: .top)