The reason why it doesn't work with your example is that you are using scaledToFill()
modifier on image, and here it matters in this particular case.
First you declared ZStack
which is itself doesn't ignore safe area. After you put Image
and resizable
. What resizable does, is it stretches the image to fit its view, in your case it is the ZStack
.
Let's see what we have until now.We have an image which stretches till the safe area.
ZStack {
Image("Breakfast").resizable()
}

So from now on you put edgesIgnoringSafeArea
on Image
, which lets the image cover all the area(ignore safe area).
Now you have Zstack
which respects safe area, and Image
which ignores safe area. This let you put VStack
in ZStack
and add staff inside it. VStack
will fill its parent view, which is ZStack
, so it too will respect safe area(See code and image below).
ZStack {
Image("Breakfast").resizable().edgesIgnoringSafeArea(.all)
VStack {
Text("hello")
Spacer()
}
}

And here at last you add .scaledToFill()
modifier, which stretches the image to contain all the area, and by doing this it makes ZStack
view to become the hole area, as fitting view's (ZStack, HStack, VStack) calculates its size based on its content.

Useful link:
Fitting and filling views in SwiftUI
How to resize a SwiftUI Image and keep its aspect ratio