NEW: Learn to build the incredible iOS 15 Weather app today! >>

How to inset the safe area with custom content

Paul Hudson    @twostraws   

Updated for Xcode 13.2

New in iOS 15

SwiftUI provides a safeAreaInset() modifier that lets us place content outside the device’s safe area, while also having other views adjust their layout so their content remains visible – it effectively shrinks the safe area to ensure all content can be seen as intended. This is different from ignoresSafeArea(), which merely extends a view’s edges so they go edge to edge.

For example, a list would normally scroll to the very end of the screen, but we could place something outside the safe area at the bottom and have the list automatically adjust its insets so all its contents are visible when we scroll to its end:

NavigationView {
    List(0..<100) { i in
        Text("Row \(i)")
    }
    .navigationTitle("Select a row")
    .safeAreaInset(edge: .bottom) {
        Text("Outside Safe Area")
            .font(.largeTitle)
            .foregroundColor(.white)
            .frame(maxWidth: .infinity)
            .padding()
            .background(.indigo)
    }
}

Download this as an Xcode project

The end of a SwiftUI list with a safe area inset view placed below, colored indigo.

Important: Before iOS 15.2 this worked only with ScrollView, but from 15.2 and later this also works with List and Form.

If you need extra space between your content and the safe area inset content, add a spacing parameter like this: .safeAreaInset(edge: .bottom, spacing: 20).

You can also add an alignment to your safe area inset content, which is useful for times when it doesn’t take up the full amount of available space. For example, we could place an information button in the bottom trailing corner like this:

NavigationView {
    List(0..<100) { i in
        Text("Row \(i)")
    }
    .navigationTitle("Select a row")
    .safeAreaInset(edge: .bottom, alignment: .trailing) {
        Button {
            print("Show help")
        } label: {
            Image(systemName: "info.circle.fill")
                .font(.largeTitle)
                .symbolRenderingMode(.multicolor)
                .padding(.trailing)
        }
        .accessibilityLabel("Show help")
    }
}

Download this as an Xcode project

The end of a SwiftUI list with an 'i' button in the bottom-right corner.

Tip: You can apply safeAreaInset() multiple times if needed, and each inset will take into account the previous insets.

Hacking with Swift is sponsored by Essential Developer

SPONSORED Learn the most up-to-date techniques and strategies for testing new and legacy Swift code in this free practical course for iOS devs who want to become complete Senior iOS Developers.

Learn more

Sponsor Hacking with Swift and reach the world's largest Swift community!

Similar solutions…

BUY OUR BOOKS
Buy Pro Swift Buy Swift Design Patterns Buy Testing Swift Buy Hacking with iOS Buy Swift Coding Challenges Buy Swift on Sundays Volume One Buy Server-Side Swift (Vapor Edition) Buy Advanced iOS Volume One Buy Advanced iOS Volume Two Buy Advanced iOS Volume Three Buy Hacking with watchOS Buy Hacking with tvOS Buy Hacking with macOS Buy Dive Into SpriteKit Buy Swift in Sixty Seconds Buy Objective-C for Swift Developers Buy Server-Side Swift (Kitura Edition) Buy Beyond Code

Was this page useful? Let us know!

Average rating: 5.0/5

 
Unknown user

You are not logged in

Log in or create account
 

Link copied to your pasteboard.