I have created a DragGesture in a View that should select a @State(Bool) whether the user swipe left or right.
The thing is that only swiping right is detected.
How to use .gesture() to capture whether a user is swiping left or right on his screen?
import SwiftUI
struct SwiftUIView: View {
//MARK: Value to change on swipe gesture
@State var swipeRight: Bool
var body: some View {
VStack {
//MARK: Value displayed after user swiped
Text($swipeRight ? "Right" : "Left")
}
.gesture(
DragGesture()
.onChanged { (value) in
//MARK: What is it missing here?
switch value.location.x {
case ...(-0.5):
self.swipeRight = false
print("Swipe Left return false")
case 0.5...:
self.swipeRight = true
print("Swipe Right return true")
default: ()
}
})
}
I made a small improvement in @emehex code that will allow you to choose direction
extension View {
public func dismissingGesture(tolerance: Double = 24, direction: DragGesture.Value.Direction, action: @escaping () -> ()) -> some View {
gesture(DragGesture()
.onEnded { value in
let swipeDirection = value.detectDirection(tolerance)
if swipeDirection == direction {
action()
}
}
)
}
}
extension DragGesture.Value {
func detectDirection(_ tolerance: Double = 24) -> Direction? {
if startLocation.x < location.x - tolerance { return .left }
if startLocation.x > location.x + tolerance { return .right }
if startLocation.y > location.y + tolerance { return .up }
if startLocation.y < location.y - tolerance { return .down }
return nil
}
enum Direction {
case left
case right
case up
case down
}
}
.dismissingGesture(direction: .right){
// perform action
}