Building a Bottom Sheet in SwiftUI with a Scrolling Option

Quinton Pryce
1v1Me Blog
Published in
2 min readJun 1, 2023

As the modern user interface leans towards more gesture-based navigation, it's common to encounter the "bottom sheet" interface — a card that slides up from the bottom covering part of the screen. In this post, we'll look at creating a customizable bottom sheet in SwiftUI, and we will even add the ability to handle large content by making it scrollable.

Creating a Basic Bottom Sheet

First, we start by creating the BottomSheet struct. This struct is a SwiftUI View that takes a title, a BottomSheetCloser and a closure for the content of the sheet. The BottomSheetCloser is an ObservableObject that provides a simple interface to open and close the sheet.

The bottom sheet is presented as a ZStack with a semi-transparent black background and the sheet itself. The sheet uses a GeometryReader to adjust the offset for the slide-up animation.

Adding Scrolling Capability

For larger contents, the bottom sheet may end up taking too much of the screen real estate. This is where the ScrollingBottomSheet comes in. This struct is a wrapper around the BottomSheet that makes the content scrollable when it exceeds a certain height. The decision to use either a plain content or a ScrollView is done dynamically based on the calculated content height.

The content height is calculated using a GeometryReader overlay on the content. This overlay doesn't affect the content's appearance or interaction but allows us to read its size.

The Future: Swipe to Dismiss & Improvements

There's always room for improvement and expansion. One potential enhancement could be the ability to swipe down the sheet to dismiss it.

In the time I spent looking at this code, I only now realize there are some things in here that not all bottom sheets have (title, backgrounds, close buttons). These could be generalized away, but for 1v1Me it makes it easy to spin up a consistent header & background for the sheets without having to constantly use “ThemedBottomSheet.swift” all the time.

--

--

Quinton Pryce
1v1Me Blog

iOS Developer | Camper | Believer in Resilience