Hello everyone,
I am trying to use BottomSheet (UISheetPresentationController) in my project and there is an issue where I can't automatically dismiss bottom sheet when I move back to parent view.
For reproduction steps, I have essentially:
- Home view with button to go to next view
- Next view has bottom sheet that automatically opens
- When I go back to parent view, the bottom sheet is still open
To use BottomSheet in SwiftUI, I used bottomSheet by adamfootdev (I also used a similar method based on createwithswift, but both had same issues so I don't think there is an issue with implementation). Also to solve the issue, I first tried using onDisappear and found out it was not called early enough, so I used onWillDisappear from stack overflow.
Below is the main reproduction steps:
import SwiftUI
import BottomSheet
// Based on https://github.com/adamfootdev/BottomSheet
struct BottomSheetParent: View {
@State var isPresented: Bool = false
var body: some View {
VStack {
Button(action: {isPresented.toggle()}) {
Text("Press For Bottom Sheet")
}
}
.bottomSheet(isPresented: $isPresented, largestUndimmedDetentIdentifier: .large) {
Text("Hello from Bottom Sheet")
}
// onDisappear was not early enough, so I tried onWillDisappear
// Based on https://stackoverflow.com/questions/59745663/is-there-a-swiftui-equivalent-for-viewwilldisappear-or-detect-when-a-view-is
//.onWillDisappear() {
// isPresented = false
//}
}
}
struct BottomSheetReproHome: View {
var body: some View {
NavigationLink(destination: BottomSheetParent()) {
Text("Button To Next Screen")
}
}
}
struct BottomSheetReproHome_Previews: PreviewProvider {
static var previews: some View {
NavigationView {
BottomSheetReproHome()
}
}
}
To use bottom sheet, add following dependency
dependencies: [
.package(url: "https://github.com/adamfootdev/BottomSheet.git", from: "0.1.3")
]
You can uncomment out onWillDisappear to see exactly what I tried. If you have a better solution, you don't have to use this. To use it add the following for onWillDisappear:
import UIKit
import SwiftUI
struct WillDisappearHandler: UIViewControllerRepresentable {
func makeCoordinator() -> WillDisappearHandler.Coordinator {
Coordinator(onWillDisappear: onWillDisappear)
}
let onWillDisappear: () -> Void
func makeUIViewController(context: UIViewControllerRepresentableContext<WillDisappearHandler>) -> UIViewController {
context.coordinator
}
func updateUIViewController(_ uiViewController: UIViewController, context: UIViewControllerRepresentableContext<WillDisappearHandler>) {
}
typealias UIViewControllerType = UIViewController
class Coordinator: UIViewController {
let onWillDisappear: () -> Void
init(onWillDisappear: @escaping () -> Void) {
self.onWillDisappear = onWillDisappear
super.init(nibName: nil, bundle: nil)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
onWillDisappear()
}
}
}
struct WillDisappearModifier: ViewModifier {
let callback: () -> Void
func body(content: Content) -> some View {
content
.background(WillDisappearHandler(onWillDisappear: callback))
}
}
extension View {
func onWillDisappear(_ perform: @escaping () -> Void) -> some View {
self.modifier(WillDisappearModifier(callback: perform))
}
}
You can see that bottom sheet does not disappear when I move back to parent view. How do I solve this issue?
I tried onWillDisappear, but this was almost a solution because when I swipe back, that dismissed the bottom sheet and not go back to parent view. The back button did what it is supposed to though.