SwiftUI.cc
Patterns
PatternModalsIntermediate

SwiftUI Custom Bottom Sheet

A customizable bottom sheet modal in SwiftUI for presenting content interactively.

Updated 2026-06
Interactive Custom Bottom Sheet with Multiple Detents
import SwiftUI

struct BottomSheetView: View {
    @State private var showingSheet = false
    
    var body: some View {
        Button("Show Bottom Sheet") {
            showingSheet = true
        }
        .sheet(isPresented: $showingSheet) {
            CustomBottomSheetContent()
                .presentationDetents([.medium, .large])
        }
    }
}

struct CustomBottomSheetContent: View {
    var body: some View {
        ScrollView {
            VStack(spacing: 16) {
                RoundedRectangle(cornerRadius: 4)
                    .frame(width: 40, height: 5)
                    .foregroundColor(.gray.opacity(0.5))
                    .padding(.top, 8)
                
                Text("Custom Bottom Sheet")
                    .font(.title2)
                    .fontWeight(.bold)
                
                Text("This is a fully customizable bottom sheet modal. You can adjust colors, fonts, and detent sizes to fit your app's design.")
                    .multilineTextAlignment(.center)
                    .padding(.horizontal)
                
                Button(action: {}) {
                    Text("Primary Action")
                        .foregroundColor(.white)
                        .padding()
                        .frame(maxWidth: .infinity)
                        .background(Color.blue)
                        .cornerRadius(12)
                }
                
                Button(action: {}) {
                    Text("Secondary Action")
                        .foregroundColor(.blue)
                        .padding()
                        .frame(maxWidth: .infinity)
                        .background(Color.blue.opacity(0.1))
                        .cornerRadius(12)
                }
                
                Spacer(minLength: 32)
            }
            .padding(.horizontal)
        }
    }
}

#Preview {
    BottomSheetView()
}

How It Works

The custom bottom sheet in SwiftUI leverages the .sheet() modifier and the .presentationDetents() API introduced in iOS 16. This allows developers to define specific heights (or detents) at which the bottom sheet can rest — typically .medium and .large. When a user interacts with the sheet, they can drag it between these states.

Inside the sheet content, a ScrollView ensures that the content remains scrollable when it exceeds the available screen space. The top handle — a small rounded rectangle — gives users a visual cue for dragging. Buttons and text are styled with padding and corner radii to create a clean, modern interface. The entire layout is wrapped in a VStack to organize content vertically.

Customization

Parameter Where to change Example values
Sheet background color In the background() modifier of the content .white, .blue.opacity(0.1)
Text color and font In Text() and .foregroundColor() modifiers .black, .font(.title)
Button styles Inside the Button() views Change background color, corner radius
Detent sizes In .presentationDetents() [.medium], [.large]
Handle color In the RoundedRectangle() view .gray, .black

Accessibility Notes

Ensure buttons have descriptive labels and consider adding .accessibilityLabel() for screen readers. Use sufficient contrast between text and background colors to support readability.