I want to offset a view when a sheet comes up and set it back when the sheet gets dismissed. The code itself works, but I have a problem.
When the sheet first comes up, everything is running as expected. But when I dismiss the sheet, there is a ~ 1 second delay before the offset goes back to 0. (Running it in the actual simulator shows the same result)
How can I get rid of the delay or control the delay duration?
My code:
import SwiftUI
struct FirstView: View {
@State var showSheet: Bool = false
var body: some View {
Text("Hello, World!")
.onTapGesture {
showSheet.toggle()
}
.sheet(isPresented: $showSheet) {
LaggyView()
.presentationDetents([.medium, .large])
}
.offset(y: showSheet ? -300 : 0)
.animation(.default, value: showSheet)
}
}
struct LaggyView: View {
var body: some View {
Text("hello")
}
}
struct FirstView_Previews: PreviewProvider {
static var previews: some View {
FirstView()
}
}
The way I solved this was by setting isPresented
to false before the sheet could set it.
To do this I set a .coordinateSpace(name: “someName”)
on the top level view and wrapped both the view that has the sheet modifier on it and the sheet content in GeometryReaders.
In the sheet content I used the sheet geometry proxy’s frame in the top level named coordinate space and the wrapping view’s geometry frame in the global coordinate space to determine if the offset of the sheet content is greater than the maxY of the global frame. I had to add a bit of a buffer to account for the top portion of the sheet with the drag indicator.
struct OuterView: View {
var body: some View {
ContentView()
.coordinateSpace(name: "someName")
}
}
struct ContentView: View {
@State private var isPresented = false
var body: some View {
GeometryReader { containingGeometry in
EmptyView()
.sheet(isPresented: $isPresented) {
GeometryReader { geometry in
let frame = geometry.frame(in: .named("someName"))
let globalFrame = containingGeometry.frame(in: .global)
let buffer = 50.0
EmptyView()
.onChange(of: frame.origin.y) { newValue in
if newValue > globalFrame.maxY + buffer {
withAnimation {
isPresented = false
}
}
}
}
}
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With