This is my first question on here.
I want padding at the edges of this View:
struct Test3: View {
var body: some View {
VStack {
ZStack {
Color.blue
Image("SplashPage")
.resizable()
.scaledToFill()
}
ZStack {
Color.gray
Button("touch me", action: {})
}
.frame(width: .infinity, height: 48)
}
.padding(24)
}
}
I've searched here and thought this post would solve my problems:
.clipped() -> Nope.
I've searched online. Asked ChatGPT. Looked at hackingwithswift. Looking for "mask image SwiftUI" and "SwiftUI clip image to ZStack"
... nope.
I've been trying to nail down what I'm doing wrong and I just can't figure it out:


I have a VStack which contains 2 ZStacks. This VStack has padding of 24 all around.
In the first VStack, I added an image that is .resizable() and .scaledToFill()
I expected the image to be clipped respecting the 24 point padding. I expect this to respect the padding on an iPhone SE and an iPhone 14 Pro or whatever large emulator.
The second VStack has a button with .frame(width: .infinity, height: 48). If I comment this line out, then the image behaves as expected!
This problem is being caused by the
scaledToFill()on theImage. It seems to fill the full screen width and ignores the padding at the sides.You found it was working when you removed the
.framemodifier from the secondZStack. I am not sure why this helped, but there was a separate issue here too. Setting awidthof.infinityis invalid (and I was seeing errors in the console). It needs to bemaxWidthinstead.So here are a couple of workarounds for the image scaling:
1. Surround the
Imagewith aGeometryReaderA
GeometryReadercan be used to measure the space that is really available and this size can be set on theImage. After setting the size, it also needs to be.clipped().2. Show the
Imageas an overlayThe
Colorthat you are using in the background will expand to fill all of the space available. If theImageis applied as an overlay to thisColorthen it will adopt the same frame size. The surroundingZStackis then redundant and can be omitted.With this approach, the
.clipped()modifier needs to be applied after the overlay to theColor, not to theImage.The result is the same in both cases: