Updated for Xcode 14.2
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 want that, add presentationDragIndicator(.hidden)
to the contents of your sheet, 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])
.presentationDragIndicator(.hidden)
}
}
}
Download this as an Xcode project
Tip: If you don’t ask for any detent, the default is .large
.
Be careful: 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
SPONSORED From March 20th to 26th, you can join a FREE crash course for mid/senior iOS devs who want to achieve an expert level of technical and practical skills – it’s the fast track to being a complete senior developer!
Sponsor Hacking with Swift and reach the world's largest Swift community!
Link copied to your pasteboard.