Skip to content

Instantly share code, notes, and snippets.

@fatbobman
Created April 5, 2024 06:59
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save fatbobman/8b4a17e94fd14653b48f3454b847f640 to your computer and use it in GitHub Desktop.
Save fatbobman/8b4a17e94fd14653b48f3454b847f640 to your computer and use it in GitHub Desktop.
a dynamic sheet demo
import SwiftUI
struct ContentView: View {
@State var show = false
@State var height: CGFloat = 250
var body: some View {
List {
Button("Pop Sheet") {
height = 250
show.toggle()
}
Button("Pop ScrollView Sheet") {
height = 1000
show.toggle()
}
}
.adaptiveSheet(isPresent: $show) {
ViewThatFits(in: .vertical) {
SheetView(height: height)
ScrollView {
SheetView(height: height)
}
}
}
}
}
struct SheetView: View {
let height: CGFloat
var body: some View {
Text("Hi")
.frame(maxWidth: .infinity, minHeight: height)
.presentationBackground(.orange)
}
}
extension View {
func adaptiveSheet<Content: View>(isPresent: Binding<Bool>, @ViewBuilder sheetContent: () -> Content) -> some View {
modifier(AdaptiveSheetModifier(isPresented: isPresent, sheetContent))
}
}
struct AdaptiveSheetModifier<SheetContent: View>: ViewModifier {
@Binding var isPresented: Bool
@State private var subHeight: CGFloat = 0
var sheetContent: SheetContent
init(isPresented: Binding<Bool>, @ViewBuilder _ content: () -> SheetContent) {
_isPresented = isPresented
sheetContent = content()
}
func body(content: Content) -> some View {
content
.background(
sheetContent // 在此获取尺寸,防止初次弹出抖动
.background(
GeometryReader { proxy in
Color.clear
.task(id: proxy.size.height) {
subHeight = proxy.size.height
}
}
)
.hidden()
)
.sheet(isPresented: $isPresented) {
sheetContent
.presentationDetents([.height(subHeight)])
}
.id(subHeight)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment