BLACK FRIDAY SALE: Save big on all my Swift books and bundles! >>

How to display a bottom sheet

Paul Hudson    @twostraws   

Updated for Xcode 14.0 beta 1

New in iOS 16

SwiftUI’s presentationDetents() modifier lets us create sheets that slide up from the bottom of our view, but occupy only part of the screen – how much is down to us, and we have as much or as little control as we want.

To use the modifier, provide it with a set of the sizes you want to support, like this:

struct ContentView: View {
    @State private var showingCredits = false

    var body: some View {
        Button("Show Credits") {
            showingCredits.toggle()
        }
        .sheet(isPresented: $showingCredits) {
            Text("This app was brought to you by Hacking with Swift")
                .presentationDetents([.medium, .large])
        }
    }
}

Download this as an Xcode project

By supporting both .medium (about half the screen) and .large (all the screen), SwiftUI will create a resize handle to let the user adjust the sheet between those two sizes. If you don’t ask for any detent, the default is .large.

Important: Even with custom presentation detents in place, sheets will automatically take up the full screen when there’s a compact height size class – an iPhone in landscape, for example. Make sure you provide a way to dismiss your sheet if you support this scenario.

As well as specifying one of the built-in sizes, you can also provide a custom fraction in the range of 0 through 1. For example, this creates a sheet taking up the bottom 15% of the screen:

struct ContentView: View {
    @State private var showingCredits = false

    var body: some View {
        Button("Show Credits") {
            showingCredits.toggle()
        }
        .sheet(isPresented: $showingCredits) {
            Text("This app was brought to you by Hacking with Swift")
                .presentationDetents([.fraction(0.15)])
        }
    }
}

Download this as an Xcode project

Or you can specify an exact point height like this:

struct ContentView: View {
    @State private var showingCredits = false

    var body: some View {
        Button("Show Credits") {
            showingCredits.toggle()
        }
        .sheet(isPresented: $showingCredits) {
            Text("This app was brought to you by Hacking with Swift")
                .presentationDetents([.height(300)])
        }
    }
}

Download this as an Xcode project

You can attach as many detents to your views as you need – just add them all to the set of detents, and SwiftUI will take care of the rest. For example, this lets the user go between 10% and 100% in 10% steps:

struct ContentView: View {
    @State private var showingCredits = false

    let heights = stride(from: 0.1, through: 1.0, by: 0.1).map { PresentationDetent.fraction($0) }

    var body: some View {
        Button("Show Credits") {
            showingCredits.toggle()
        }
        .sheet(isPresented: $showingCredits) {
            Text("This app was brought to you by Hacking with Swift")
                .presentationDetents(Set(heights))
        }
    }
}

Download this as an Xcode project

Hacking with Swift is sponsored by RevenueCat

SPONSORED In-app subscriptions are a pain to implement, hard to test, and full of edge cases. RevenueCat makes it straightforward and reliable so you can get back to building your app. Oh, and it's free if your app makes less than $10k/mo.

Learn more

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

Similar solutions…

BUY OUR BOOKS
Buy Pro Swift Buy Pro SwiftUI 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 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 Beyond Code

Was this page useful? Let us know!

Average rating: 4.1/5

 
Unknown user

You are not logged in

Log in or create account
 

Link copied to your pasteboard.