Last active
November 19, 2025 07:43
-
-
Save scifisatan/2f62899c9129b0712070f41e6f7a167a to your computer and use it in GitHub Desktop.
A view modifier that presents a sheet which automatically adjusts its height according to its content.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import SwiftUI | |
| /// A view modifier that presents a sheet which automatically adjusts its height | |
| /// to fit the content inside. This avoids hardcoding heights and makes the sheet reusable. | |
| /// Usage: Call .adaptiveSheet(isPresented:content:) on any view. | |
| /// | |
| /// - Parameters: | |
| /// - isPresented: Binding controlling presentation. | |
| /// - content: A SwiftUI ViewBuilder for the sheet's body. | |
| struct AdaptiveSheet: ViewModifier { | |
| @Binding var isPresented: Bool | |
| @State private var sheetHeight: CGFloat = 300 | |
| let sheetContent: () -> AnyView | |
| func body(content: Content) -> some View { | |
| content | |
| .sheet(isPresented: $isPresented) { | |
| // The sheet's content, wrapped in GeometryReader to measure height | |
| sheetContent() | |
| .background( | |
| // GeometryReader updates sheetHeight with the actual content height | |
| GeometryReader { geometry in | |
| Color.clear | |
| .task { | |
| sheetHeight = geometry.size.height | |
| } | |
| } | |
| ) | |
| // .id(sheetHeight) causes the view to refresh if the height changes | |
| .id(sheetHeight) | |
| // Apply the dynamic height detent to the sheet | |
| .presentationDetents([.height(sheetHeight)]) | |
| } | |
| } | |
| } | |
| /// Extension to apply AdaptiveSheet as a simple modifier on any SwiftUI view. | |
| /// - Parameters: | |
| /// - isPresented: Binding to show/hide the sheet | |
| /// - content: ViewBuilder for sheet content | |
| extension View { | |
| func adaptiveSheet<Content: View>( | |
| isPresented: Binding<Bool>, | |
| @ViewBuilder content: @escaping () -> Content | |
| ) -> some View { | |
| self.modifier(AdaptiveSheet(isPresented: isPresented, sheetContent: { AnyView(content()) })) | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment