Is it possible to use swipe to dismiss while presenting a fullscreen modal in iOS 13?
Asked Answered
S

3

5

With the new default card modal presentation in iOS 13, there is a nice feature that is swipe to dismiss. Is it possible to use this feature while presenting a classic .fullscreen modal?

I checked and if isModalInPresentation is false while presenting in fullscreen.

Any ideas?

Salyer answered 5/9, 2019 at 10:42 Comment(0)
D
3

It seems that the swipe to dismiss will only work if the modal is presented as a sheet, as stated in this year's wwdc:

Now, what do you all have to do to support Pull to Dismiss? In general, nothing. If you present something as a Sheet, the ability to pull it down comes for free.

And it makes sense. When you present it as a sheet, the UI makes it look like you can swipe the modal down. When you present it on fullscreen, it would not be intuitive for the user that he should swipe the page down to dismiss. I'd rather use a button on this case.

Deel answered 5/9, 2019 at 11:54 Comment(0)
B
2

As @pepsy said, the full screen view is not intended to be dismissed by swiping. However, if you still want to try it, here's something I started

NOTE: it's a bit glitchy the parent controller is not visible while dragging.

I added a UIPanGestureRecognizer to the view to simulate the swipe to dismiss behavior. I also have a Close (X) button, as the swipe gesture is not as intuitive as for a sheet.

@IBAction func panGestureRecognizerHandler(_ sender: UIPanGestureRecognizer) {

    let translationY = sender.translation(in: sender.view!).y

    switch sender.state {
    case .began:
        break
    case .changed:
        view.transform = CGAffineTransform(translationX: 0, y: translationY)
    case .ended, .cancelled:
        if translationY > 160 {
            dismiss(animated: true, completion: nil)
        } else {
            UIView.animate(withDuration: 0.2, animations: {
                self.view.transform = CGAffineTransform(translationX: 0, y: 0)
            })
        }
    case .failed, .possible:
        break
    @unknown default:
        break
    }
}
Birdhouse answered 17/6, 2020 at 1:13 Comment(0)
S
2

This works for me:

struct SwipeFullScreenCover: View {

    @GestureState private var dragOffset = CGSize.zero
    
    @Environment(\.presentationMode) var presentationMode
    
    var body: some View {
        ZStack{ .... }
            .gesture(DragGesture().updating($dragOffset, body: { (value, state, transaction) in
                if(value.startLocation.x < 20 &&
                   value.translation.width > 100) {
                    self.presentationMode.wrappedValue.dismiss()
                }
            }))
    }
}
Snoddy answered 18/1 at 5:11 Comment(3)
Thank you for your work, it was helpful to me.Thomism
You saved my life charm.Despairing
Very strange, this question had no activity in a long time and then, someone posted a new answer and it has three upvotes and two comments in the space of 10 minutes...Salyer

© 2022 - 2024 — McMap. All rights reserved.