SwiftUI: Present alert on user swiping to dismiss

Viewed 938

Just wondering --- as of 2020 --- if there is a built-in way in the SwiftUI package to enhance the "swipe to dismiss" gesture on Sheets.

I've been to this question here: Prevent dismissal of modal view controller in SwiftUI --- doesn't work (at least not anymore) and Xcode doesn't suggest a fix/migration on the code provided in the upvoted answer.

Also been to a few other posts, but they either point to the linked answer above, or suggest 3rd party packages. (I'm trying to avoid those because SwiftUI is rapidly evolving and better stick to what Apple officially provides for now.)

So to sum, is there a way to ---

  1. Prevent users from dismissing a Sheet (not a FullScreenCover) by swiping down
  2. Optionally present an alert or do any other thing, like when you go to Calendar.app, create an event, type a few letters and try to dismiss it
  3. ... All without using 3rd party libraries?

Thanks.

2 Answers

Here is a demo of native SwiftUI approach to block sheet closing - just provide background with drag gesture.

Tested with Xcode 12 / iOS 14

demo

struct DemoSheetNoClose: View {
    @State private var showSheet = false
    var body: some View {
        Button("Show Sheet") { self.showSheet.toggle() }
            .sheet(isPresented: $showSheet) {
                ZStack {
                    Rectangle().fill(Color.red).border(Color.black) // << just demo
                        .edgesIgnoringSafeArea(.all)
                        .highPriorityGesture(DragGesture(minimumDistance: 0).onEnded { value in
                            // handle value here to, for example, show alert
                        })

                    Text("Content Here!")
                }
            }
    }
}

Note: it can be made as view wrapper, modifier, etc.

It is now 2022 and iOS 16 with the next SwiftUI iteration will be released shortly.

It seems that @Asperi 's answer is still the only way to achieve it. I hope I'm wrong and now there's a more polished API from Apple?

Related