How to Create a SwiftUI Sheet That Fits Its Content
Have you ever wanted to show a sheet in your SwiftUI app that’s just as tall as it needs to be? Today, we’ll learn how to make a reusable component that does exactly that!
Create the ContentSizedSheet View
First, let’s make our new view:
struct ContentSizedSheet<Content: View>: View {
@Binding var isPresented: Bool
let content: () -> Content
var body: some View {
ZStack {
if isPresented {
Color.black.opacity(0.3)
.ignoresSafeArea()
.onTapGesture { isPresented = false }
VStack {
content()
.padding()
.background(Color.white)
.cornerRadius(10)
.padding()
Spacer()
}
.transition(.move(edge: .bottom))
.animation(.default, value: isPresented)
}
}
}
}
Use the ContentSizedSheet
Now, let’s see how to use our new view:
struct ContentView: View {
@State private var showSheet = false
var body: some View {
Button("Show Sheet") {
showSheet = true
}
.contentSizedSheet(isPresented: $showSheet) {
VStack {
Text("This is a custom sheet!")
Text("It's as tall as it needs to be.")
Button("Close") {
showSheet = false
}
}
}
}
}
Create a View Extension
To make our new view easier to use, let’s add an extension:
extension View {
func contentSizedSheet<Content: View>(
isPresented: Binding<Bool>,
@ViewBuilder content: @escaping () -> Content
) -> some View {
self.overlay(
ContentSizedSheet(isPresented: isPresented, content: content)
)
}
}
That’s it! Now you have a reusable component for content-sized sheets in SwiftUI. The sheet will appear from the bottom of the screen and will be just tall enough to fit its content. You can use it in any of your SwiftUI views by calling the contentSizedSheet modifier.