Skip to content

Instantly share code, notes, and snippets.

@alobaili
Created November 10, 2024 10:39
Show Gist options
  • Save alobaili/43aa2fea8885cf237e360373bf903652 to your computer and use it in GitHub Desktop.
Save alobaili/43aa2fea8885cf237e360373bf903652 to your computer and use it in GitHub Desktop.
A SwiftUI view modifier that fits a sheet height to its contents.
import SwiftUI
fileprivate struct ReadHeightModifier: ViewModifier {
let action: (Double) -> Void
func body(content: Content) -> some View {
content
.onGeometryChange(for: Double.self) { proxy in
proxy.size.height
} action: { newValue in
action(newValue)
}
}
}
struct FittedPresentationDetentModifier: ViewModifier {
@State private var height = 0.0
func body(content: Content) -> some View {
content
.readHeight { height in
/*
this guard is to avoid the following layout error that will
crash in future releases:
A presentation preference is rapidly switching between values,
possibly because the presentation's preferences depend on its size.
-- Previous Preferences --
presentationsDetents: Height 389.3333333333333
-- Most Recent Preferences --
presentationsDetents: Height 376.6666666666667
The most recent value was ignored to avoid cyclic layout.
Please update your code to avoid this issue.
This may become a crash in a future release.
*/
guard height >= self.height else { return }
self.height = height
}
.presentationDetents([.height(height)])
}
}
extension View {
func readHeight(_ perform: @escaping (Double) -> Void) -> some View {
modifier(ReadHeightModifier(action: perform))
}
func fittedPresentationDetent() -> some View {
modifier(FittedPresentationDetentModifier())
}
}
#Preview {
Color.clear
.sheet(isPresented: .constant(true)) {
DatePicker("", selection: .constant(.now), displayedComponents: .date)
.datePickerStyle(.graphical)
.fittedPresentationDetent()
}
}
#Preview {
Color.clear
.sheet(isPresented: .constant(true)) {
VStack {
Text("Example")
Text("Example")
Text("Example")
}
.fittedPresentationDetent()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment