Extend a footer outside the Safe Area with SwiftUI
Subscribe to my channel to be notified when new videos about SwiftUI are released.
The safe area is one of the most relevant changes in the UI paradigm of iOS in the recent years. It unified a bunch of layout ideas into a single API and allowed us to make our UIs adapt to new phones with weird shapes.
One of the most common design patterns that has to deal with the bottom safe area is having a call to action inside a footer on your screen. The difficulty with this design is that you want your content to respect the safe area, but also you want a background that extends to the edge of the screen. You can see it in action in any TabBar
:
Implementing this is not as straightforward as it may seem. If you expand your container to the edge, your content will be behind the home indicator. If you fully respect the safe area you will see a different colored background behind the home indicator.
What you need is a combination of both things.
Luckily SwiftUI gives us the tools we need to accomplish this.
Updated solution for iOS 15 using the new API safeAreaInset(edge:alignment:spacing:content:)
With the new safeAreaInset(edge:alignment:spacing:content:)
modifier the way we work with safe areas has changed. Instead of applying a modifier to a view in the main layout making it extend, we apply a modifier to the main view passing another view that we want to extend to the edges.
VStack(spacing: 0) {
// Your screen content...
}
.safeAreaInset(edge: .bottom, spacing: 0) {
VStack {
// Your footer content or CTA
// It will respect the safe area
}
.padding()
.frame(maxWidth: .infinity)
// The background will extend automatically to the edge
.background(Color.green)
}
Note how you can specify a spacing
between the main content (the modified view) and the footer view.
Solution for iOS 14
This solution works on iOS 14. SwiftUI behaviour has changed a bit since the first releases. Thanks to Matthias for pointing it out.
edgesIgnoringSafeArea
is a modifier that lets a view ignore the safe areas. We can use this to tell the background of our footer to extend to the edge of the screen.
VStack(spacing: 0) {
// Your screen content...
VStack {
// Your footer content or CTA
}
.padding()
.frame(maxWidth: .infinity)
// The background we want to extend
.background(Color.green.edgesIgnoringSafeArea(.bottom))
}
By using the modifier only on the background with still make the rest of the content respect the safe areas which is very important.
Solution for iOS 13
Watch the original video to check the solution we had back in 2020.