I got this code:
#if DEBUG
struct BottomViewPreview: View {
var body: some View {
Spacer()
Text("S").ignoresSafeArea(edges: .bottom)
}
}
#Preview {
BottomViewPreview()
}
#endif
I would suspect the S Text
would be at the bottom, ignoring the safe space but it does not work. What is the correct way of doing this? I don't want ANY padding at the bottom.
The main reason why the Text
does not change its size or position when you add the modifier .ignoresSafeArea
is because, unlike a Color
or a Shape
, a Text
view is not greedy. It does not need more space than it already uses, so it does not expand into the safe area inset.
If you add a background color to the Text
using the modifier background(_:ignoresSafeAreaEdges:)
then it will appear as if the frame of the text does extend to the screen edge:
Text("S")
.background(.yellow)
.ignoresSafeArea(edges: .bottom)
This is misleading. What is actually happening, is that the background color is ignoring the safe area edge, not the Text
. Adding a .border
to the Text
is a better way to confirm that the modifier .ignoresSafeArea
is having no effect:
Text("S")
.border(.red)
.ignoresSafeArea(edges: .bottom)
}
To make the frame of the Text
extend into the safe area inset, you can apply .frame(maxHeight: .infinity)
, before adding the modifier .ignoresSafeArea
. However, this will cause it to use as much vertical space as possible, both above and below the actual text.
To have the Text
consume only the space in the safe area inset below it, you can give a higher .layoutPriority
to the Spacer
above it. Let's put the two views in a VStack
too:
VStack {
Spacer()
.layoutPriority(2)
Text("S")
.frame(maxHeight: .infinity)
.layoutPriority(1)
.border(.red)
.ignoresSafeArea(edges: .bottom)
}
By default, the .frame
modifier uses alignment .center
, which is why the text is now in the middle of the frame. Add an alignment
parameter if you want a different alignment:
Text("S")
.frame(maxHeight: .infinity, alignment: .top)
// ...other modifiers as before
If in fact you want the text to move completely into the safe area inset, you need to apply .ignoreSafeArea
to the container instead:
VStack {
Spacer()
Text("S")
.border(.red)
}
.ignoresSafeArea(edges: .bottom)
However, this screenshot illustrates why it may be a bad idea to ignore the safe area edges for a container with Text
at the bottom, because the text might end up being obscured by the home bar.