How to Implement Swipe to Dismiss in SwiftUI FullScreenCover
When it comes to creating immersive and interactive user experiences, the swipe-to-dismiss gesture for modals has become increasingly popular in iOS apps. In this blog post, we’ll explore how to implement swipe-to-dismiss functionality for full-screen modals using SwiftUI’s fullScreenCover
.
Swipe to Dismiss in Any Direction
The Code
Here’s the code example that allows you to dismiss the modal by swiping in any direction:
import SwiftUI
struct ContentView: View {
@State private var isModalPresented = false
var body: some View {
Button("Show Modal") {
isModalPresented = true
}
.fullScreenCover(isPresented: $isModalPresented) {
VStack{
Text("Hello, Full-Screen Modal!")
}.frame(maxWidth: .infinity, maxHeight: .infinity)
.contentShape(Rectangle()).background(.yellow)
.gesture(
DragGesture(minimumDistance: 50, coordinateSpace: .local)
.onEnded { _ in
isModalPresented = false
}
)
}
}
}
Code Explanation
@State private var isModalPresented = false
: This state variable controls the presentation of the modal..contentShape(Rectangle())
: This makes the entire area of the modal receptive to gestures.DragGesture(minimumDistance: 50, coordinateSpace: .local)
: Initiates a drag gesture that triggers when the drag covers at least 50 points.
The .onEnded { _ in isModalPresented = false }
part specifies what should happen when the drag gesture ends: in this case, the modal will be dismissed.
Customize the Swipe Direction
By default, the example allows for dismissing the modal by swiping in any direction. You can, however, specify a direction by examining the value passed to the onEnded
closure.
The Code
Here’s a code snippet that allows the modal to be dismissed only when swiped in downward direction:
import SwiftUI
struct ContentView: View {
@State private var isModalPresented = false
var body: some View {
Button("Show Modal") {
isModalPresented = true
}
.fullScreenCover(isPresented: $isModalPresented) {
VStack{
Text("Hello, Full-Screen Modal!")
}.frame(maxWidth: .infinity, maxHeight: .infinity)
.contentShape(Rectangle()).background(.yellow)
.gesture(
DragGesture(minimumDistance: 50, coordinateSpace: .local)
.onEnded {value in
if value.translation.height > 50 {
isModalPresented = false
}
}
)
}
}
}
Code Explanation
value in if value.translation.height > 50
: This line specifies that the modal should only be dismissed if it is swiped downwards by more than 50 points.
We use the value
parameter in the .onEnded
closure to access the translation
property, which contains the distance moved during the swipe. If the distance in the vertical direction (height
) is greater than 50, we dismiss the modal.
Implementing swipe-to-dismiss in SwiftUI’s full-screen modals is not only possible but also incredibly straightforward. You have the freedom to either allow a swipe in any direction for a dismiss action or to specify a particular direction. This makes it easier to tailor the user experience to fit the context of your application.