Skip to content

Instantly share code, notes, and snippets.

@goergisn
Last active December 19, 2022 22:08
Show Gist options
  • Save goergisn/f1f1199e2fe22d44e118dea21053469a to your computer and use it in GitHub Desktop.
Save goergisn/f1f1199e2fe22d44e118dea21053469a to your computer and use it in GitHub Desktop.
A SwiftUI sheet that sizes itself based on the height needed by the contained view
extension View {
func fittingSheet<Content: View>(
isPresented: Binding<Bool>,
backgroundColor: Color? = nil,
additionalDetents: Set<PresentationDetent> = [],
shouldShowDragIndicator: Bool = true,
onDismiss: (() -> Void)? = nil,
content: @escaping () -> Content
) -> some View {
modifier(FittingSheet(isPresented: isPresented,
backgroundColor: backgroundColor,
additionalDetents: additionalDetents,
shouldShowDragIndicator: shouldShowDragIndicator,
onDismiss: onDismiss,
sheetContent: content))
}
}
struct FittingSheet<SheetContent: View>: ViewModifier {
@Binding
var isPresented: Bool
let backgroundColor: Color?
let additionalDetents: Set<PresentationDetent>
let shouldShowDragIndicator: Bool
let onDismiss: (() -> Void)?
let sheetContent: () -> SheetContent
@State
private var height: CGFloat = 0
func body(content: Content) -> some View {
content
.sheet(
isPresented: $isPresented,
onDismiss: onDismiss
) {
ZStack {
backgroundColor?.ignoresSafeArea()
sheetContent()
.frame(maxWidth: .infinity)
.background(
GeometryReader { proxy in
Color.clear
.onAppear {
self.height = proxy.size.height
}
}
)
.presentationDetents(Set([.height(height)] + additionalDetents))
.presentationDragIndicator(.visible)
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment